Stream: fhirpath
Topic: Dates and Quantitiy arithmetic
Paul Lynch (May 17 2019 at 15:45):
The simple implementation of Date & Quantity arithmetic I had hoped to implement in fhirpath.js was as follows:
1) Convert the date (or datetime, or time) to milliseconds
2) Use our JavaScript UCUM conversion library (ucum-lhc) to convert the quantity to milliseconds
3) Add/subtract the quantity ms from the date ms
4) Convert back to a date string and truncate to the precision of the date
However, having read the resolutions to GF#20682, GF#14089, and GF#13365, it seems like things are a lot more complicated, and from a UCUM point of view, inconsistent. As I understand the behavior from the spec, we have:
- @2019-02-01 + 1 'mo' = @2019-03-01
- @2019-02-01 + 30.4375 'd' = @2019-03-03 (even though in UCUM 1 'mo' = 30.4375 'd')
- @2019-02-01 + 1.0001 ' mo' = @2019-03-03 (because the month amount is no longer a whole number, and gets interpreted per UCUM)
- @2019-01-30 + 1 'mo' = ???
Is that correct?
Grahame Grieve (May 17 2019 at 22:26):
yes that's correct. (including the last one ;-) )
Paul Lynch (May 17 2019 at 22:27):
:-) So, the "last one" was meant as a hidden question. Are you saying the answer to @2019-01-30 + 1 'mo' is undefined (or maybe throws an error?)
Grahame Grieve (May 17 2019 at 22:28):
no I think it should not be undefined or result in an error - both would be very unmanagable in practice, but I do not know what the result should be. I just asked my daughter (since she was around) the question in plain english context and she wasn't sure what the right answer is
Paul Lynch (May 20 2019 at 14:58):
@Bryn Rhodes ?
Ewout Kramer (May 20 2019 at 15:37):
And I guess @2019-03-31 + 1 'mo' = ?
Ewout Kramer (May 20 2019 at 15:38):
Asked my firely colleagues here.... the common tendency seems to be "end of the next month"
Ewout Kramer (May 20 2019 at 15:39):
And now, @2016-02-29 + 1 'a' ?
Ewout Kramer (May 20 2019 at 15:39):
That would be @2017-02-28 by the same logic.
Ewout Kramer (May 20 2019 at 15:40):
Could be a pain to implement. Let's me check what the .NET stack does...
Ewout Kramer (May 20 2019 at 15:42):
Yep:
new DateTime(2019,01,30).AddMonths(1) == new DateTime(2019,2,28)
Ewout Kramer (May 20 2019 at 15:43):
new DateTime(2016,02,29).AddYears(1) == new DateTime(2017,2,28)
Paul Lynch (May 20 2019 at 18:08):
@2019-02-28 + 1 'mo' = @2019-03-28 ?
Then:
@2019-01-31 + 1 'mo' + 1 'mo' = @2019-03-28
Jean Duteau (May 20 2019 at 18:09):
And @2019-01-31 + 2 'mo' = @2019-03-31?
Ewout Kramer (May 20 2019 at 19:08):
It is on the .NET stack.
Paul Lynch (May 20 2019 at 19:51):
moment.js also behaves that way. I guess we can live with that behavior.
Bryn Rhodes (May 20 2019 at 20:14):
CQL defines this behavior according to the ISO 8601 guidelines, which allow for "agreement": https://cql.hl7.org/05-languagesemantics.html#datetime-arithmetic-1
Bryn Rhodes (May 20 2019 at 20:19):
And yes, that's consistent with the .NET and Java stacks, same behavior.
Bryn Rhodes (May 20 2019 at 20:22):
The one clarification I would suggest here is that 1.0001 'mo'
doesn't make sense in this context, because a month isn't a definite quantity. The Java engine ignores the fractional component so that @2019-02-01 + 1.0001 'mo'
is actually @2019-03-01
.
Paul Lynch (May 20 2019 at 20:24):
'mo' is a definite quantity in UCUM. I think that is why the resolution of those tracker items follow the UCUM definition for non-whole numbers.
Bryn Rhodes (May 20 2019 at 20:46):
Right, we're just saying that when you use UCUM months and years in calendar calculations, the calculations round for calendar semantics, consistent with ISO 8601 definitions.
Ewout Kramer (May 21 2019 at 08:23):
And the only way to add calender months in .NET is using the AddMonths() function as shown above, which takes an integer parameter.
Paul Lynch (Jun 04 2019 at 14:24):
The spec currently says, "For partial date/time values, the operation is performed by converting the time-valued quantity to the highest precision in the partial...." I assume that is only done if the time-valued quantity is at a higher precision than the partial date/time? Otherwise, if one follows that sentence as written, @2019-01-01 + 1 'a' would need to be converted to @2019-01-01 + 365 'd' before processing the addition, which would cause problems in leap years. I think if the text is changed to limit that conversion to when the partial date/time has less precision than the quantity, it should be okay.
Bas van den Heuvel (Jun 06 2019 at 10:01):
What is the current situation on this topic?
If I understand the topic correctly. The operations like @2014-02-04T15:32:29 + 1 'mo'. Adding UCUM values to FHIRPath Date/DateTime/Time values is not allowed.
Is this true?
(related to tracker item 21601https://gforge.hl7.org/gf/project/fhir/tracker/?action=TrackerItemEdit&tracker_item_id=21601)
Ewout Kramer (Jun 06 2019 at 15:32):
I think that a clarification will be added to the FhirPath spec describing the logic we discussed in this thread.
Paul Lynch (Jun 06 2019 at 15:32):
@Bas van den Heuvel See the recent resolution of https://gforge.hl7.org/gf/project/fhir/tracker/?action=TrackerItemEdit&tracker_item_id=20682&start=0. Quantities with UCUM units are still allowed to be added to date/time.
Paul Lynch (Jun 06 2019 at 15:46):
The spec currently says, "For partial date/time values, the operation is performed by converting the time-valued quantity to the highest precision in the partial...." I assume that is only done if the time-valued quantity is at a higher precision than the partial date/time? Otherwise, if one follows that sentence as written, @2019-01-01 + 1 'a' would need to be converted to @2019-01-01 + 365 'd' before processing the addition, which would cause problems in leap years. I think if the text is changed to limit that conversion to when the partial date/time has less precision than the quantity, it should be okay.
Bryn Rhodes (Jun 08 2019 at 22:20):
@Paul Lynch , thank you for submitting that, that is definitely the intent and I agree with the proposed clarification to address it.
Last updated: Apr 12 2022 at 19:14 UTC