Browse Source

Fixed rewrite of time zone without DST (#54398)

We try to rewrite time zones to fixed offsets in the date histogram aggregation
if the data in the shard is within a single transition.
However this optimization is not applied on time zones that don't apply daylight saving changes
but had some random transitions in the past (e.g. Australia/Brisbane or Asia/Katmandu).
This changes fixes the rewrite of such time zones to fixed offsets.
Jim Ferenczi 5 years ago
parent
commit
c20dc0256c

+ 2 - 2
server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/DateHistogramAggregationBuilder.java

@@ -467,7 +467,7 @@ public class DateHistogramAggregationBuilder extends ValuesSourceAggregationBuil
 
         ZoneOffsetTransition prevOffsetTransition = tz.getRules().previousTransition(instant);
         final long prevTransition;
-        if (prevOffsetTransition  != null) {
+        if (prevOffsetTransition != null) {
             prevTransition = prevOffsetTransition.getInstant().toEpochMilli();
         } else {
             prevTransition = instant.toEpochMilli();
@@ -477,7 +477,7 @@ public class DateHistogramAggregationBuilder extends ValuesSourceAggregationBuil
         if (nextOffsetTransition != null) {
             nextTransition = nextOffsetTransition.getInstant().toEpochMilli();
         } else {
-            nextTransition = instant.toEpochMilli();
+            nextTransition = Long.MAX_VALUE; // fixed time-zone after prevTransition
         }
 
         // We need all not only values but also rounded values to be within

+ 12 - 0
server/src/test/java/org/elasticsearch/search/aggregations/bucket/histogram/DateHistogramTests.java

@@ -170,6 +170,18 @@ public class DateHistogramTests extends BaseAggregationTestCase<DateHistogramAgg
                     assertSame(tz, builder.rewriteTimeZone(shardContextThatDoesntCross));
                     assertSame(tz, builder.rewriteTimeZone(shardContextThatCrosses));
 
+                    // timeZone without DST => always rewrite
+                    tz = ZoneId.of("Australia/Brisbane");
+                    builder.timeZone(tz);
+                    assertSame(ZoneOffset.ofHours(10), builder.rewriteTimeZone(shardContextThatDoesntCross));
+                    assertSame(ZoneOffset.ofHours(10), builder.rewriteTimeZone(shardContextThatCrosses));
+
+                    // another timeZone without DST => always rewrite
+                    tz = ZoneId.of("Asia/Katmandu");
+                    builder.timeZone(tz);
+                    assertSame(ZoneOffset.ofHoursMinutes(5, 45), builder.rewriteTimeZone(shardContextThatDoesntCross));
+                    assertSame(ZoneOffset.ofHoursMinutes(5, 45), builder.rewriteTimeZone(shardContextThatCrosses));
+
                     // daylight-saving-times => rewrite if doesn't cross
                     tz = ZoneId.of("Europe/Paris");
                     builder.timeZone(tz);