FEEL date and time functions: dates, durations, time zones and calendar arithmetic
FEEL guide · 12 built-in functions · DMN 1.6
Deadlines, ages, notice periods and opening hours make dates the most common source of logic in DMN decision tables, and of bugs. FEEL has four temporal types: date, time, date and time and duration. Durations come in two kinds that do not mix. This guide covers the constructors, the calendar functions and the arithmetic between them.
Each result was computed by the FEEL engine behind the evaluator at the top. Examples that depend on the current moment say so.
All FEEL date and time functions at a glance
| Function | Signature | Returns |
|---|---|---|
| now | now() | Returns the current date and time |
| today | today() | Returns the current date |
| day of year | day of year(date) | Returns the ordinal day within the year, 1 to 366 |
| day of week | day of week(date) | Returns the English weekday name of the date |
| month of year | month of year(date) | Returns the English month name of the date |
| week of year | week of year(date) | Returns the ISO 8601 week number of the date |
| last day of month | last day of month(date) | Returns the day number of the last day of the value's month (28, 29, 30 or 31), handy for billing-period and deadline logic |
| date | date(from) or date(year, month, day) | Creates a date from an ISO 8601 string, from year/month/day components, or by truncating a date and time value |
| time | time(from) or time(hour, minute, second, offset?) | Creates a time from an ISO 8601 string, from components, or by extracting the time of a date and time value |
| date and time | date and time(from) or date and time(date, time) | Creates a date and time from an ISO 8601 string or by combining a date with a time |
| duration | duration(from) | Creates a days-and-time or years-and-months duration from an ISO 8601 string |
| years and months duration | years and months duration(from, to) | Returns the duration between two dates as whole years and months, dropping smaller units |
Creating dates: strict ISO 8601
date("2026-07-24"), date(2026, 7, 24) and the literal @"2026-07-24" all create the same value. The string form accepts only ISO 8601, with zero-padded months and days. A malformed or impossible date gives null, not an error, so the mistake often surfaces later as an unexpected null.
date(2026, 7, 24) = @"2026-07-24"
date(date and time("2026-07-24T13:00:00"))
Truncate a date and time to its date.
Date arithmetic and the difference between two dates
Add or subtract a duration to move a date. Subtracting two dates gives a days-and-time duration; read .days to get the difference in days.
Be careful when adding months to the 29th, 30th or 31st. DMN 1.6 defines date plus months as the same day of the month in the target month (Table 58), so 31 January plus one month would be 31 February, which does not exist, and the result is null. Engines differ here, and some move to the last day of the month instead. A model that should run unchanged on any engine avoids adding months to those days.
A date has no time of day, so adding hours only moves it once they add up to whole days.
date("2026-07-24") - duration("P30D")
date("2026-07-24") in [date("2026-01-01")..date("2026-12-31")]
Ranges work for dates too, which helps in decision table rules.
Two kinds of duration
A days-and-time duration (P3D, PT2H30M) is an exact length of time. A years-and-months duration (P1Y, P6M) is a calendar amount: one month is 28 to 31 days depending on where you start. The two cannot be compared or added to each other. years and months duration(from, to) gives the calendar difference between two dates, which is how you compute an age.
duration("P1D") = duration("PT24H")
date("2026-03-01") - date("2026-02-01")
The difference of two dates is a days-and-time duration.
years and months duration(date("2000-03-15"), date("2026-07-24")).years
Age in whole years.
Time zones
A date and time may be local (no zone), have a UTC offset (+02:00, Z), or name an IANA zone (@Europe/Zurich). Values with zone information compare by instant. When a local value is compared with a zoned one, DMN 1.6 says the local value takes the other value's offset (Table 55). Not every engine implements that rule, so keep the inputs of a decision either all local or all zoned. Subtracting a local value from a zoned one is undefined, and the result is null.
date and time("2026-07-24T14:30:00+02:00") = date and time("2026-07-24T12:30:00Z")
date and time("2026-07-24T14:30:00@Europe/Zurich").timezone
date and time("2026-07-24T14:30:00") < date and time("2026-07-24T15:00:00+02:00")
The local value is read as 14:30+02:00.
Day of week, week numbers and month ends
day of week and month of year return English names, so compare them with strings such as "Saturday". For a number, use the .weekday component (1 = Monday). week of year follows ISO 8601: weeks start on Monday, and the days around New Year can belong to the neighbouring year's week.
day of week(date("2026-07-24")) = "Friday"
Function reference
Each function with its examples and edge cases. The heading links to the function's own page with its parameter table.
now
now()
Returns the current date and time.
DMN 1.6 notes that now() and today() are not deterministic and recommends isolating decision logic that uses them in its own decision, so that tests can override it with a fixed value. In practice, pass the reference date in as an input variable wherever you can. The engine behind this site reads the clock once per evaluation, so every call in one expression sees the same instant.
now()
now() instance of date and time
today() = date(now())
today
today()
Returns the current date.
today()
today() instance of date
day of year
day of year(date)
Returns the ordinal day within the year, 1 to 366.
day of year(date("2026-07-24"))
day of week
day of week(date)
Returns the English weekday name of the date.
day of week(date("2026-07-24"))
day of week(date and time("2026-07-24T23:30:00"))
Works on date and time values too.
month of year
month of year(date)
Returns the English month name of the date.
month of year(date("2026-07-24"))
week of year
week of year(date)
Returns the ISO 8601 week number of the date.
week of year(date("2026-01-01"))
week of year(date("2026-07-24"))
week of year(date("2027-01-01"))
week of year(date("2024-12-30"))
last day of month
last day of month(date)
Not part of the DMN 1.6 standard: an extension supported by the engine behind this site. A model that uses it may not run on other DMN engines.
Returns the day number of the last day of the value's month (28, 29, 30 or 31), handy for billing-period and deadline logic.
last day of month(date("2026-02-10"))
last day of month(date("2024-02-10"))
last day of month(date and time("2026-04-10T10:00:00"))
date
date(from) or date(year, month, day)
Creates a date from an ISO 8601 string, from year/month/day components, or by truncating a date and time value.
The string form is strict ISO 8601, YYYY-MM-DD with zero-padded month and day. Anything else, including impossible dates such as 30 February, gives null rather than an error, so a mistyped date shows up later as a null result. The @"2026-07-24" literal is shorthand for the same thing.
date("2026-07-24")
date(2026, 7, 24)
date(date and time("2026-07-24T13:00:00"))
date("2026-07-24T10:00:00")
A date and time string is not a date string. Wrap it: date(date and time(...)).
date(2026, 13, 1)
date(date and time("2026-07-24T10:00:00"))
To get the date of a date and time, convert the value, not the string.
time
time(from) or time(hour, minute, second, offset?)
Creates a time from an ISO 8601 string, from components, or by extracting the time of a date and time value.
time("14:30:00")
time(14, 30, 0, duration("PT1H"))
time("14:30:00") - time("08:00:00")
time("25:00:00")
date and time
date and time(from) or date and time(date, time)
Creates a date and time from an ISO 8601 string or by combining a date with a time.
A value can be local (no zone), carry a UTC offset such as +02:00 or Z, or name an IANA zone with @. Values with an offset compare by instant. When a local value is compared with a zoned one, DMN 1.6 lets the local value take the other value's offset (Table 55). Engines do not all implement that rule, so keep the inputs of a decision either all local or all zoned.
date and time("2026-07-24T14:30:00")
date and time(date("2026-07-24"), time("14:30:00"))
date and time("2026-07-24T14:30:00+02:00") = date and time("2026-07-24T12:30:00Z")
Same instant.
date and time("2026-07-24T14:30:00@Europe/Zurich").timezone
duration
duration(from)
Creates a days-and-time or years-and-months duration from an ISO 8601 string.
FEEL has two duration types that do not mix. Days-and-time durations (P3D, PT2H) are exact amounts of time. Years-and-months durations (P1Y, P6M) are calendar amounts whose length depends on the month. Comparing one with the other gives null, because a month is not a fixed number of days.
Durations are normalized: PT90M becomes PT1H30M and P14M becomes P1Y2M. Weeks (P2W) are not part of the notation. The components are available as .days, .hours, .minutes, .seconds, .years and .months.
duration("P3DT4H")
duration("P1Y6M")
date("2026-07-01") + duration("P3D")
duration("P1D") = duration("PT24H")
duration("P1Y") = duration("P12M")
duration("PT2H") * 3
date("2026-07-24") + duration("P" + string(5) + "D")
Build a duration from a number by concatenating the ISO string.
years and months duration
years and months duration(from, to)
Returns the duration between two dates as whole years and months, dropping smaller units.
years and months duration(date("2024-01-10"), date("2026-07-24"))
years and months duration(date("2000-03-15"), date("2026-07-24")).years
A common way to compute an age in whole years.
How B-FEEL differs
In standard FEEL an invalid argument makes the result null. The business-friendly
B-FEEL dialect returns a type default instead. Both columns were evaluated by the same engine:
| Expression | FEEL | B-FEEL |
|---|---|---|
| day of week(null) | null | (empty string) |
| month of year(null) | null | (empty string) |
More FEEL guides
FEEL string functions · FEEL numeric functions · FEEL list functions · Language constructs · Examples cheat sheet
Defined by the OMG DMN 1.6 specification, chapter 10.3.4 (built-in functions).