mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-26 14:54:56 +00:00
There are edge cases where rounding a date to a certain interval using a time zone with DST shifts can currently cause the rounded date to be bigger than the original date. This happens when rounding a date closely after a DST start and the rounded date falls into the DST gap. Here is an example for CET time zone, where local time is set forward by one hour at 2016-03-27T02:00:00+01:00 to 2016-03-27T03:00:00.000+02:00: The date 2016-03-27T03:01:00.000+02:00 (1459040460000) which is just after the DST change is first converted to local time (1459047660000). If we then apply interval rounding for a 14m interval in local time, this takes us to 1459047240000, which unfortunately falls into the DST gap. When converting this back to UTC, joda provides options to throw exceptions on illegal dates like this, or correct this by adjusting the date to the new time zone offset. We currently do the later, but this leads to converting this illegal date back to 2016-03-27T03:54:00.000+02:00 (1459043640000), giving us a date that is larger than the original date we wanted to round. This change fixes this by using the "strict" option of 'convertLocalToUTC()' to detect rounded dates that fall into the DST gap. If this happens, we can use the time of the DST change instead as the interval start. Even before this change, intervals around DST shifts like this can be shorter than the desired interval. This, for example, happens when the requested interval width doesn't completely fit into the remaining time span when the DST shift happens. For example, using a 14m interval in UTC+1 (CET before DST starts) leads to the following valid rounding values around the time where DST happens: 2016-03-27T01:30:00+01:00 2016-03-27T01:44:00+01:00 2016-03-27T01:58:00+01:00 2016-03-27T02:12:00+01:00 2016-03-27T02:26:00+01:00 ... while the rounding values in UTC+2 (CET after DST start) are placed like this around the same time: 2016-03-27T02:40:00+02:00 2016-03-27T02:54:00+02:00 2016-03-27T03:08:00+02:00 2016-03-27T03:22:00+02:00 ... From this we can see then when we switch from UTC+1 to UTC+2 at 02:00 the last rounding value in UTC+1 is at 01:58 and the first valid one in UTC+2 is at 03:08, so even if we decide to put all the dates in between into one rounding interval, it will only cover 10 minutes. With this change we choose to use the moment of DST shift as an aditional interval separator, leaving us with a 2min interval from [01:58,02:00) before the shift and an 8min interval from [03:00,03:08) after the shift. This change also adds tests for the above example and adds randomization to the existing TimeIntervalRounding tests.