diff --git a/processing/src/main/java/io/druid/granularity/PeriodGranularity.java b/processing/src/main/java/io/druid/granularity/PeriodGranularity.java index cc8faf66d41..260e1ab4dbe 100644 --- a/processing/src/main/java/io/druid/granularity/PeriodGranularity.java +++ b/processing/src/main/java/io/druid/granularity/PeriodGranularity.java @@ -301,14 +301,17 @@ public class PeriodGranularity extends BaseQueryGranularity return current; } - private long truncateMillisPeriod(long t) + protected long truncateMillisPeriod(final long t) { // toStandardDuration assumes days are always 24h, and hours are always 60 minutes, // which may not always be the case, e.g if there are daylight saving changes. - if(chronology.days().isPrecise() && chronology.hours().isPrecise()) { + if (chronology.days().isPrecise() && chronology.hours().isPrecise()) { final long millis = period.toStandardDuration().getMillis(); - t -= t % millis + origin % millis; - return t; + long offset = t % millis - origin % millis; + if(offset < 0) { + offset += millis; + } + return t - offset; } else { diff --git a/processing/src/test/java/io/druid/granularity/QueryGranularityTest.java b/processing/src/test/java/io/druid/granularity/QueryGranularityTest.java index 9d0eb0287f0..af6f95165ed 100644 --- a/processing/src/test/java/io/druid/granularity/QueryGranularityTest.java +++ b/processing/src/test/java/io/druid/granularity/QueryGranularityTest.java @@ -347,66 +347,99 @@ public class QueryGranularityTest @Test public void testCompoundPeriodTruncate() throws Exception { - final DateTime origin = new DateTime("2012-01-02T05:00:00.000-08:00"); - QueryGranularity periodOrigin = new PeriodGranularity(new Period("P1M2D"), - origin, - DateTimeZone.forID("America/Los_Angeles")); - assertSame( - Lists.newArrayList( - new DateTime("2011-11-30T05:00:00.000-08:00"), - new DateTime("2012-01-02T05:00:00.000-08:00"), - new DateTime("2012-02-04T05:00:00.000-08:00"), - new DateTime("2012-02-04T05:00:00.000-08:00") - ), - Lists.newArrayList( - periodOrigin.truncate(new DateTime("2012-01-01T05:00:04.123-08:00").getMillis()), - periodOrigin.truncate(new DateTime("2012-01-02T07:00:04.123-08:00").getMillis()), - periodOrigin.truncate(new DateTime("2012-03-01T07:20:04.123-08:00").getMillis()), - periodOrigin.truncate(new DateTime("2012-02-04T05:00:00.000-08:00").getMillis()) - ) - ); + { + final DateTime origin = new DateTime("2012-01-02T05:00:00.000-08:00"); + QueryGranularity periodOrigin = new PeriodGranularity( + new Period("P1M2D"), + origin, + DateTimeZone.forID("America/Los_Angeles") + ); + assertSame( + Lists.newArrayList( + new DateTime("2011-11-30T05:00:00.000-08:00"), + new DateTime("2012-01-02T05:00:00.000-08:00"), + new DateTime("2012-02-04T05:00:00.000-08:00"), + new DateTime("2012-02-04T05:00:00.000-08:00") + ), + Lists.newArrayList( + periodOrigin.truncate(new DateTime("2012-01-01T05:00:04.123-08:00").getMillis()), + periodOrigin.truncate(new DateTime("2012-01-02T07:00:04.123-08:00").getMillis()), + periodOrigin.truncate(new DateTime("2012-03-01T07:20:04.123-08:00").getMillis()), + periodOrigin.truncate(new DateTime("2012-02-04T05:00:00.000-08:00").getMillis()) + ) + ); - QueryGranularity periodNoOrigin = new PeriodGranularity(new Period("P1M2D"), - null, - DateTimeZone.forID("America/Los_Angeles")); - assertSame( - Lists.newArrayList( - new DateTime("1970-01-01T00:00:00.000-08:00"), - new DateTime("2011-12-12T00:00:00.000-08:00"), - new DateTime("2012-01-14T00:00:00.000-08:00"), - new DateTime("2012-02-16T00:00:00.000-08:00") - ), - Lists.newArrayList( - periodNoOrigin.truncate(new DateTime("1970-01-01T05:02:04.123-08:00").getMillis()), - periodNoOrigin.truncate(new DateTime("2012-01-01T05:02:04.123-08:00").getMillis()), - periodNoOrigin.truncate(new DateTime("2012-01-15T07:01:04.123-08:00").getMillis()), - periodNoOrigin.truncate(new DateTime("2012-02-16T00:00:00.000-08:00").getMillis()) + QueryGranularity periodNoOrigin = new PeriodGranularity( + new Period("P1M2D"), + null, + DateTimeZone.forID("America/Los_Angeles") + ); + assertSame( + Lists.newArrayList( + new DateTime("1970-01-01T00:00:00.000-08:00"), + new DateTime("2011-12-12T00:00:00.000-08:00"), + new DateTime("2012-01-14T00:00:00.000-08:00"), + new DateTime("2012-02-16T00:00:00.000-08:00") + ), + Lists.newArrayList( + periodNoOrigin.truncate(new DateTime("1970-01-01T05:02:04.123-08:00").getMillis()), + periodNoOrigin.truncate(new DateTime("2012-01-01T05:02:04.123-08:00").getMillis()), + periodNoOrigin.truncate(new DateTime("2012-01-15T07:01:04.123-08:00").getMillis()), + periodNoOrigin.truncate(new DateTime("2012-02-16T00:00:00.000-08:00").getMillis()) - ) - ); + ) + ); + } + + { + final DateTime origin = new DateTime("2012-01-02T05:00:00.000-08:00"); + QueryGranularity periodOrigin = new PeriodGranularity( + new Period("PT12H5M"), + origin, + DateTimeZone.forID("America/Los_Angeles") + ); + assertSame( + Lists.newArrayList( + new DateTime("2012-01-01T04:50:00.000-08:00"), + new DateTime("2012-01-02T05:00:00.000-08:00"), + new DateTime("2012-01-02T17:05:00.000-08:00"), + new DateTime("2012-02-03T22:25:00.000-08:00") + ), + Lists.newArrayList( + periodOrigin.truncate(new DateTime("2012-01-01T05:00:04.123-08:00").getMillis()), + periodOrigin.truncate(new DateTime("2012-01-02T07:00:04.123-08:00").getMillis()), + periodOrigin.truncate(new DateTime("2012-01-03T00:20:04.123-08:00").getMillis()), + periodOrigin.truncate(new DateTime("2012-02-03T22:25:00.000-08:00").getMillis()) + ) + ); + } } @Test public void testCompoundPeriodMillisTruncate() throws Exception { - final DateTime origin = new DateTime("2012-01-02T05:00:00.000-08:00"); - QueryGranularity periodOrigin = new PeriodGranularity(new Period("PT12H5M"), - origin, - DateTimeZone.forID("America/Los_Angeles")); - assertSame( - Lists.newArrayList( - new DateTime("2012-01-01T04:50:00.000-08:00"), - new DateTime("2012-01-02T05:00:00.000-08:00"), - new DateTime("2012-01-02T17:05:00.000-08:00"), - new DateTime("2012-02-03T22:25:00.000-08:00") - ), - Lists.newArrayList( - periodOrigin.truncate(new DateTime("2012-01-01T05:00:04.123-08:00").getMillis()), - periodOrigin.truncate(new DateTime("2012-01-02T07:00:04.123-08:00").getMillis()), - periodOrigin.truncate(new DateTime("2012-01-03T00:20:04.123-08:00").getMillis()), - periodOrigin.truncate(new DateTime("2012-02-03T22:25:00.000-08:00").getMillis()) - ) - ); + { + final DateTime origin = new DateTime("2012-01-02T05:00:00.000-08:00"); + QueryGranularity periodOrigin = new PeriodGranularity( + new Period("PT12H5M"), + origin, + DateTimeZone.UTC + ); + assertSame( + Lists.newArrayList( + new DateTime("2012-01-01T04:50:00.000-08:00"), + new DateTime("2012-01-02T05:00:00.000-08:00"), + new DateTime("2012-01-02T17:05:00.000-08:00"), + new DateTime("2012-02-03T22:25:00.000-08:00") + ), + Lists.newArrayList( + periodOrigin.truncate(new DateTime("2012-01-01T05:00:04.123-08:00").getMillis()), + periodOrigin.truncate(new DateTime("2012-01-02T07:00:04.123-08:00").getMillis()), + periodOrigin.truncate(new DateTime("2012-01-03T00:20:04.123-08:00").getMillis()), + periodOrigin.truncate(new DateTime("2012-02-03T22:25:00.000-08:00").getMillis()) + ) + ); + } } @Test @@ -524,7 +557,7 @@ public class QueryGranularityTest while (actualIter.hasNext() && expectedIter.hasNext()) { long a = actualIter.next().longValue(); - Assert.assertEquals(expectedIter.next().getMillis(), a); + Assert.assertEquals(expectedIter.next(), new DateTime(a)); } Assert.assertFalse("actualIter not exhausted!?", actualIter.hasNext()); Assert.assertFalse("expectedIter not exhausted!?", expectedIter.hasNext());