DMN Date Arithmetic


#1

Hi,

I have a business rule where I need to test if an input date is more than two years old. Hence ideally Id like to write an expression something like;

< Sysdate() - 2 (eg years)

< Sysdate() - 730 (eg days)

I guess I could put the logic in a java class and integrate the class, or I could use a groovy script etc. However Im wondering if anyone has a more elegant way, or even a way of doing this in FEEL?

regards

Rob


Add time period to input date in DMN Table
Dates in DMN
#2

While not “elegant”, you could simply calculate the difference between the current system date and the arbitrary value of days representing 2 years. This difference could then be assigned to a process variable and applied to an input column of the DMN table.

Depending upon how accurate this needs to be, you might have to account for leap years in your calculations. Personally, I prefer to use UNIX epoch type dates (number of seconds between now and 01-01-1970 00:00:00). This provides an absolute reference and is easily used in calculations.

You could also set up an input column to use the FEEL date and time function to determine if a date was inside the valid range represented by a period of current date - 2 years. The challenge here would be to automatically calculate a period of 2 years and set the input value to it. The date functions are described here:

https://docs.camunda.org/manual/7.4/reference/dmn11/feel/language-elements/

I think the easiest thing would be to use JavaScript or Groovy to calculate some sort of absolute number (days or epoch seconds) difference between now and two years back, and then compare it to a fixed value in an input column.


#3

Hi Rob,

you can use Joda Time or Java 8 date & time functions to calculate with dates.

However, the specification of FEEL provides date functions that would fit your use case (e.g. comparison and ranges for dates). Currently, the DMN engine only supports a limited set of date functions. But if anyone have a good idea to supports more functions, it would be nice to create a pull request or community extension.

Greetings,
Philipp


#4

Hi Philip, is there a way to initialise a dmn date with the current sysdate?


#5

Hi Rob,

if you use JUEL, you can use one of the internal context functions: now() or datetime().

Does this help you?

Greetings,
Philipp


#6

Hi Philipp,

Id like to have a cell with an entry defined something like;

< date and time(now())

Hence, how do I achieve this?

R


#7

Hi Rob,

I think you can just write:

< now()

Currently, the “date and time” function only accepts strings.


#8

Thanks Philipp,

tried that, however I get an error;

FEEL-01007 Unable to resolve function ‘now’ in expression ‘< now()’

regards

Rob


#9

Hi Rob,

do you use the standalone DMN engine or the embedded one from the process engine?


#10

Embedded - hence using a business rule task inside a BPMN process… One thing to be aware of, Im using a multi-instance decorator on the business rule task in case that makes a difference…

(Also 7.5 Alpha2 on Tomcat)


#11

Hi,

please note that the now() method is only available in JUEL not FEEL. So you would have to set the inputExpression language to use juel and write a complete juel expression like cellInput < now(). But I didn’t tested it.

Cheers,
Sebastian


#12

Thanks Sebastian,

It seems simpler then to have a rule such as If yearsToExpiry > -2, then… In other words the item has not been expired for more than 2 years. Hence I could implement this as

‘> -2’

And in the input mapping, use some code to calculate number of years between now and the expiry date.

However, for elegance, in FEEL, Id love to be able to write something like;

< Now().substractYears(2)

Rationale: Im passing is a date and the logic is clear in the rule. If I use the > -2 and pass in a preprocessed number rather than date, then it may not be as obvious to business users…

regards

Rob


#13

What was outcome of this? Best practices? lessons learned? :slight_smile:


#14

I am following up on this conversation as we have encountered the same need. We need different rules for based on if the input date is 2 years ago or more, less than 2 years ago or in the future.

I believe that we need to use juel such that we can use now() method. I am thinking something along the lines of cellInput < now().substractYears(2), but this does not work I think because now is date time.

Any thoughts? Thanks! Nell


#15

Hi @nhinchey,

the function now() returns the current time as date-time (Joda-Time) object. I guess that you can call < now().minusYears(2). Does this work for you?

As an alternative, you can use the FEEL extension which supports date/time calculation and has also a now() function.

Best regards,
Philipp


#16

@Philipp_Ossler, is there an example Junit test setup that would allow for easy unit testing of individual expressions that includes the functions available to the DMN engine?


#17

Hi @clay.rowland,

you can use one of the test templates:

Best regards,
Philipp


#18

You can use this:

cellInput < dateTime().withMillis(now().getTime()).minusMonths(6).toDate()

Note: the inputEntry tag at the DMN XML need to have expressionLanguage=“juel” attibute.

Here the example:

basic-documents.dmn (1.5 KB)