Skip to content

Commit

Permalink
Aggregations: Be lenient when converting local to utc time in time zo…
Browse files Browse the repository at this point in the history
…ne roundings

This solves a problem in the time zone rounding classes where time dates that
fall into a DST gap will cause joda time library to throw an exception.
Changing the conversion methods 'strict' option to false prevents this.

Closes #10025
  • Loading branch information
Christoph Büscher committed Mar 16, 2015
1 parent 4946988 commit 6efffaf
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 5 deletions.
Expand Up @@ -157,7 +157,7 @@ public byte id() {
@Override
public long roundKey(long utcMillis) {
long local = preTz.convertUTCToLocal(utcMillis);
return preTz.convertLocalToUTC(field.roundFloor(local), true, utcMillis);
return preTz.convertLocalToUTC(field.roundFloor(local), false, utcMillis);
}

@Override
Expand All @@ -168,11 +168,11 @@ public long valueForKey(long time) {

@Override
public long nextRoundingValue(long time) {
long currentWithoutPostZone = postTz.convertLocalToUTC(time, true);
long currentWithoutPostZone = postTz.convertLocalToUTC(time, false);
// we also need to correct for preTz because rounding takes place in local time zone
long local = preTz.convertUTCToLocal(currentWithoutPostZone);
long nextLocal = durationField.add(local, 1);
return postTz.convertUTCToLocal(preTz.convertLocalToUTC((nextLocal), true));
return postTz.convertUTCToLocal(preTz.convertLocalToUTC((nextLocal), false));
}

@Override
Expand Down Expand Up @@ -283,7 +283,7 @@ public long valueForKey(long time) {

@Override
public long nextRoundingValue(long currentWithPostZone) {
long currentWithoutPostZone = postTz.convertLocalToUTC(currentWithPostZone, true);
long currentWithoutPostZone = postTz.convertLocalToUTC(currentWithPostZone, false);
long nextWithoutPostZone = durationField.add(currentWithoutPostZone, 1);
return postTz.convertUTCToLocal(nextWithoutPostZone);
}
Expand Down Expand Up @@ -386,7 +386,7 @@ public long roundKey(long utcMillis) {
public long valueForKey(long key) {
long time = Rounding.Interval.roundValue(key, interval);
// now, time is still in local, move it to UTC
time = preTz.convertLocalToUTC(time, true);
time = preTz.convertLocalToUTC(time, false);
// now apply post Tz
time = postTz.convertUTCToLocal(time);
return time;
Expand Down
Expand Up @@ -178,6 +178,25 @@ public void testNextRoundingValueCornerCase8209() {
assertThat(roundedValue, equalTo(time("2014-04-30T23:00:00.000Z", DateTimeZone.UTC)));
}

/**
* test for #10025, strict local to UTC conversion can cause joda exceptions
* on DST start
*/
@Test
public void testLenientConversionDST() {
DateTimeZone tz = DateTimeZone.forID("America/Sao_Paulo");
long start = time("2014-10-18T20:50:00.000", tz);
long end = time("2014-10-19T01:00:00.000", tz);
Rounding tzRounding = new TimeZoneRounding.TimeTimeZoneRoundingFloor(DateTimeUnit.MINUTES_OF_HOUR, tz,
DateTimeZone.UTC);
Rounding dayTzRounding = new TimeZoneRounding.DayTimeZoneRoundingFloor(DateTimeUnit.MINUTES_OF_HOUR, tz,
DateTimeZone.UTC);
for (long time = start; time < end; time = time + 60000) {
assertThat(tzRounding.nextRoundingValue(time), greaterThan(time));
assertThat(dayTzRounding.nextRoundingValue(time), greaterThan(time));
}
}

private long utc(String time) {
return time(time, DateTimeZone.UTC);
}
Expand Down

0 comments on commit 6efffaf

Please sign in to comment.