dateTime interval inclusion and time zone interaction
This is a possible issue in with dateTime intervals and testing if a date/dateTime is included. I am unsure if this is expected behavior related to how time zones are calculated.
Below is the CQL with the results commented next to the definition names. A dateTime is only included in the calculated interval if it is at least 01:00:00.000, but when the interval is written out the dateTime can be any time of the day. I would expect that all of the tests below should return "true." Adding 'Z' to the MP to enforce UTC does indeed result in all "true" tests. I also tested turning off daylight saving on my system and it didn't change the results below.
parameter "Measurement Period" Interval<DateTime> default Interval[@2021-01-01T00:00:00.000, @2022-01-01T00:00:00.000)
define "the interval": //Interval[2020-07-01T00:00:00.000, 2021-07-01T00:00:00.000)
Interval[start of "Measurement Period" - 6 months, start of "Measurement Period" + 6 months)
define "in interval 1": //false
@2020-07-01 in Interval[start of "Measurement Period" - 6 months, start of "Measurement Period" + 6 months)
define "in interval 2": //true
@2020-07-01T01:00:00.000 in Interval[start of "Measurement Period" - 6 months, start of "Measurement Period" + 6 months)
define "in interval 3": //false
@2020-07-01T00:59:59.999 in Interval[start of "Measurement Period" - 6 months, start of "Measurement Period" + 6 months)
define "in interval 4": //true
@2020-07-01 in Interval[@2020-07-01T00:00:00.000, @2021-07-01T00:00:00.000)
define "in interval 5": //true
@2020-07-01T00:00:00.000 in Interval[@2020-07-01T00:00:00.000, @2021-07-01T00:00:00.000)
define "in interval 6": //false
@2020-07-01 in "the interval"
Hi Matt!
According to the CQL spec, if a timezone is not specified it should be defaulted to the timezone of the "evaluation request":
https://cql.hl7.org/09-b-cqlreference.html#datetime-1
The cql-engine interprets that as the timezone of the local machine in which it's running. That means that if you're using the VS Code tooling, for example, it uses the local timezone on your machine. If you're running using the cqf-ruler, it uses the timezone of the server where the cqf-ruler is hosted.
The last test you've written there is actually comparing a Date to a DateTime. A Date lacks a timezone according to the spec, and therefore is less precise than a DateTime. Interval[@2021-07-01T00:00:00.000, @2022-07-01T00:00:00.000) in your local timezone in a narrower slice of time than Interval[@2021-07-01, @2022-07-01), which is a range of time that includes the time. before and after your local timezone where it may be @2021-07-01 somewhere else on the planet. In other words, the range of time where it's @2020-07-01 "anywhere" is definitely larger than the range of time where it's @2020-07-01 in your local timezone, so the last statement returning false is correct for an arbitrary timezone.
The "in" operator allows a precision specifier that allows you to say "don't use the timezone of the datetime when comparing it dates, only use the date component"
https://cql.hl7.org/09-b-cqlreference.html#in
So, the last definition should be:
define "in interval 6": //false
@2020-07-01 in day of "the interval"
I agree with what @JPercival posted, but I am curious as to why "in interval 2" is true and "in interval 3" is false. Seems odd to me so I tried running some tests of my own.
// Result is -6.0
define "Timezone from Date":
timezoneoffset from @2020-07-01
// Result is -7.0
define "Timezone from DateTime":
timezoneoffset from @2021-01-01T00:00:00.000
Looks like there may be a bit of a timezone mismatch between MDT and MST happening somewhere?