Skip to content

Commit

Permalink
feat(engine): new temporal builtin functions (#182)
Browse files Browse the repository at this point in the history
* new function: "week of year()"
* new function: "month of year()"
* new function: "day of week()"
* new function: "day of year()"
  • Loading branch information
saig0 authored Sep 14, 2020
1 parent 9ce3c29 commit 75ba032
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 5 deletions.
52 changes: 52 additions & 0 deletions docs/develop/feel-built-in-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -826,3 +826,55 @@ Returns the current date.
today()
// date("2020-07-31")
```

### day of week()

Returns the day of the week according to the Gregorian calendar. Note that it returns always the english name of the day.

* parameters:
* `date`: date/date-time
* result: string

```js
day of week(date("2019-09-17"))
// "Tuesday"
```

### day of year()

Returns the Gregorian number of the day within the year.

* parameters:
* `date`: date/date-time
* result: number

```js
day of year(date("2019-09-17"))
// 260
```

### week of year()

Returns the Gregorian number of the week within the year, according to ISO 8601.

* parameters:
* `date`: date/date-time
* result: number

```js
week of year(date("2019-09-17"))
// 38
```

### month of year()

Returns the month of the week according to the Gregorian calendar. Note that it returns always the english name of the month.

* parameters:
* `date`: date/date-time
* result: string

```js
month of year(date("2019-09-17"))
// "September"
```
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
package org.camunda.feel.impl.builtin

import org.camunda.feel.FeelEngineClock
import java.time.format.TextStyle
import java.time.temporal.WeekFields
import java.util.Locale

import org.camunda.feel.impl.builtin.BuiltinFunction.builtinFunction
import org.camunda.feel.syntaxtree.{ValDate, ValDateTime}
import org.camunda.feel.syntaxtree._
import org.camunda.feel.{Date, FeelEngineClock}

class TemporalBuiltinFunctions(clock: FeelEngineClock) {

def functions = Map(
"now" -> List(nowFunction),
"today" -> List(todayFunction)
"today" -> List(todayFunction),
"day of year" -> List(dateTimeFunction(getDayOfYear)),
"day of week" -> List(dateTimeFunction(getDayOfWeek)),
"month of year" -> List(dateTimeFunction(getMonthOfYear)),
"week of year" -> List(dateTimeFunction(getWeekOfYear))
)

private def nowFunction = builtinFunction(
Expand All @@ -29,4 +37,37 @@ class TemporalBuiltinFunctions(clock: FeelEngineClock) {
}
)

private def dateTimeFunction(function: Date => Val): ValFunction =
builtinFunction(
params = List("date"),
invoke = {
case List(ValDate(date)) => function(date)
case List(ValDateTime(date)) => function(date.toLocalDate)
case List(ValLocalDateTime(date)) => function(date.toLocalDate)
}
)

private def getDayOfYear(date: Date): ValNumber = {
val dayOfYear = date.getDayOfYear
ValNumber(dayOfYear)
}

private def getDayOfWeek(date: Date): ValString = {
val dayOfWeek = date.getDayOfWeek
val displayName = dayOfWeek.getDisplayName(TextStyle.FULL, Locale.ENGLISH)
ValString(displayName)
}

private def getMonthOfYear(date: Date): ValString = {
val month = date.getMonth
val displayName = month.getDisplayName(TextStyle.FULL, Locale.ENGLISH)
ValString(displayName)
}

private def getWeekOfYear(date: Date): ValNumber = {
val temporalField = WeekFields.ISO.weekOfWeekBasedYear()
val weekOfYear = date.get(temporalField)
ValNumber(weekOfYear)
}

}
6 changes: 5 additions & 1 deletion src/main/scala/org/camunda/feel/impl/parser/FeelParser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,11 @@ object FeelParser extends JavaTokenParsers {
| "distinct values"
| "get entries"
| "get value"
| "is defined")
| "is defined"
| "day of year"
| "day of week"
| "month of year"
| "week of year")

// list of built-in function parameter names with whitespaces
// -- other names match the 'parameter name' pattern
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package org.camunda.feel.impl.builtin
import java.time.{LocalDate, LocalTime, ZoneId, ZonedDateTime}

import org.camunda.feel.impl.FeelIntegrationTest
import org.camunda.feel.syntaxtree.{ValDate, ValDateTime}
import org.camunda.feel.syntaxtree.{ValDate, ValDateTime, ValNumber, ValString}
import org.scalatest.{BeforeAndAfter, FlatSpec, Matchers}

class BuiltinTemporalFunctionsTest
Expand All @@ -34,6 +34,11 @@ class BuiltinTemporalFunctionsTest
ZoneId.of("Europe/Berlin")
)

private val date = "date(2019,9,17)"
private val localDateTime = """date and time("2019-09-17T14:30:00")"""
private val dateTime =
"""date and time("2019-09-17T14:30:00@Europe/Berlin")"""

"The now() function" should "return the current date-time" in withClock {
clock =>
clock.currentTime(now)
Expand All @@ -46,4 +51,41 @@ class BuiltinTemporalFunctionsTest
eval(""" today() """) should be(ValDate(now.toLocalDate))
}

"The day of year() function" should "return the day within the year" in {

eval(s"day of year($date)") should be(ValNumber(260))
eval(s"day of year($localDateTime) ") should be(ValNumber(260))
eval(s"day of year($dateTime) ") should be(ValNumber(260))

eval(s""" day of year(date("2019-12-31")) """) should be(ValNumber(365))
eval(s""" day of year(date("2020-12-31")) """) should be(ValNumber(366))
}

"The day of week() function" should "return the day of the week" in {

eval(s"day of week($date)") should be(ValString("Tuesday"))
eval(s"day of week($localDateTime)") should be(ValString("Tuesday"))
eval(s"day of week($dateTime)") should be(ValString("Tuesday"))
}

"The month of year() function" should "return the month of the year" in {

eval(s"month of year($date)") should be(ValString("September"))
eval(s"month of year($localDateTime)") should be(ValString("September"))
eval(s"month of year($dateTime)") should be(ValString("September"))
}

"The week of year() function" should "return the number of week within the year" in {

eval(s"week of year($date)") should be(ValNumber(38))
eval(s"week of year($localDateTime)") should be(ValNumber(38))
eval(s"week of year($dateTime)") should be(ValNumber(38))

eval(""" week of year(date(2003,12,29)) """) should be(ValNumber(1))
eval(""" week of year(date(2004,1,4)) """) should be(ValNumber(1))
eval(""" week of year(date(2005,1,1)) """) should be(ValNumber(53))
eval(""" week of year(date(2005,1,3)) """) should be(ValNumber(1))
eval(""" week of year(date(2005,1,9)) """) should be(ValNumber(1))
}

}

0 comments on commit 75ba032

Please sign in to comment.