NIFI-15658 - Add duration arithmetic Expression Language functions for Date and Instant values#10956
NIFI-15658 - Add duration arithmetic Expression Language functions for Date and Instant values#10956Scrooge-McDucks wants to merge 2 commits intoapache:mainfrom
Conversation
exceptionfactory
left a comment
There was a problem hiding this comment.
Thanks for proposing these new functions @Scrooge-McDucks. The general concept looks helpful. On a cursory review, I recommend something along the lines of plusDuration and minusDuration, following the pattern of the action first in the name.
46262dc to
158b7dd
Compare
|
@exceptionfactory — Thanks for the review! The naming change makes a lot of sense. I’ve refactored the implementation to plusDuration and minusDuration. Please let me know if there’s anything I missed. |
|
I realized the same duration arithmetic logic should also be supported for Instant values, so I included the corresponding plusInstantDuration and minusInstantDuration functions as part of this update. I also rebased the branch down to a single commit to make the pull request easier to review. |
28baec7 to
de670da
Compare
de670da to
31cc430
Compare
| * Units are case-insensitive and accept singular/plural: second(s), minute(s), hour(s), | ||
| * day(s), week(s), month(s), year(s).</p> | ||
| */ | ||
| public final class DateAmountParser { |
There was a problem hiding this comment.
Is this class necessary for parsing the different duration expressions? There already exists the DurationFormat class in the nifi-api which does most of the durations listed here except for month and that class has nanos.
There was a problem hiding this comment.
Good call about the nanos. I can include nanoseconds as a supported unit so it aligns more closely with the Duration logic for fixed-length units.
I did now have a look at delegating to DurationFormat, but it converts everything to a fixed nanosecond count. Months and years require java.time.Period for calendar-aware arithmetic (e.g., adding 1 month to Jan 31 → Feb 28), which means we’d still need a separate path for those cases.
Happy to adjust if there’s a preferred direction here, but my thinking was that this keeps the behavior simpler.
There was a problem hiding this comment.
Added nanoseconds support and updated the docs. Let me know if you think it’s worth refactoring to leverage DurationFormat.
Summary
NIFI-15658
This adds four new NiFi Expression Language functions: plusDuration, minusDuration, plusInstantDuration, and minusInstantDuration.
These functions support human-readable duration arithmetic directly on Date and Instant values. Today, users often need to convert parsed dates or timestamps through numeric or epoch-based steps to perform simple adjustments, which is harder to read and less intuitive for common use cases.
Examples:
${date:toDate('dd-MM-yyyy'):plusDuration('1 week'):format('dd-MM-yyyy')}
${date:toDate('dd-MM-yyyy'):minusDuration('3 months'):format('dd-MM-yyyy')}
${ts:toInstant('dd-MM-yyyy HH:mm:ss', 'UTC'):plusInstantDuration('1 week'):formatInstant('dd-MM-yyyy HH:mm:ss', 'UTC')}
${ts:toInstant('dd-MM-yyyy HH:mm:ss', 'UTC'):minusInstantDuration('3 months'):formatInstant('dd-MM-yyyy HH:mm:ss', 'UTC')}
The new functions accept a string argument in the form " ", such as "1 week" or "3 months". plusDuration() and minusDuration() return Date values so they can be chained with other date functions such as format(). plusInstantDuration() and minusInstantDuration() return Instant values so they can be chained with instant functions such as formatInstant().
The implementation is calendar-aware rather than based on raw millisecond arithmetic. For example, adding one month to January 31 results in February 28 or 29 depending on the year. Supported units are seconds, minutes, hours, days, weeks, months, and years. Unit matching is case-insensitive, supports singular and plural forms, and requires a space between the numeric value and the unit.
Instant arithmetic is evaluated in UTC so results are deterministic across environments. When formatting an adjusted Instant in another time zone, the displayed time may differ due to daylight saving transitions.
Null subjects continue to return null gracefully.
Tracking
Please complete the following tracking steps prior to pull request creation.
Issue Tracking
Pull Request Tracking
NIFI-00000NIFI-00000VerifiedstatusPull Request Formatting
mainbranchVerification
Please indicate the verification steps performed prior to pull request creation.
Build
./mvnw clean install -P contrib-checkLicensing
LICENSEandNOTICEfilesDocumentation