fix compound period granularity for exact periods

This commit is contained in:
Xavier Léauté 2014-08-26 10:33:59 -07:00
parent 0d32466cad
commit 7537cf4fb1
2 changed files with 94 additions and 58 deletions

View File

@ -301,14 +301,17 @@ public class PeriodGranularity extends BaseQueryGranularity
return current; 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, // 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. // 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(); final long millis = period.toStandardDuration().getMillis();
t -= t % millis + origin % millis; long offset = t % millis - origin % millis;
return t; if(offset < 0) {
offset += millis;
}
return t - offset;
} }
else else
{ {

View File

@ -347,66 +347,99 @@ public class QueryGranularityTest
@Test @Test
public void testCompoundPeriodTruncate() throws Exception 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"), final DateTime origin = new DateTime("2012-01-02T05:00:00.000-08:00");
origin, QueryGranularity periodOrigin = new PeriodGranularity(
DateTimeZone.forID("America/Los_Angeles")); new Period("P1M2D"),
assertSame( origin,
Lists.newArrayList( DateTimeZone.forID("America/Los_Angeles")
new DateTime("2011-11-30T05:00:00.000-08:00"), );
new DateTime("2012-01-02T05:00:00.000-08:00"), assertSame(
new DateTime("2012-02-04T05:00:00.000-08:00"), Lists.newArrayList(
new DateTime("2012-02-04T05:00:00.000-08:00") new DateTime("2011-11-30T05:00:00.000-08:00"),
), new DateTime("2012-01-02T05:00:00.000-08:00"),
Lists.newArrayList( new DateTime("2012-02-04T05:00:00.000-08:00"),
periodOrigin.truncate(new DateTime("2012-01-01T05:00:04.123-08:00").getMillis()), new DateTime("2012-02-04T05:00:00.000-08:00")
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()), Lists.newArrayList(
periodOrigin.truncate(new DateTime("2012-02-04T05:00:00.000-08:00").getMillis()) 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"), QueryGranularity periodNoOrigin = new PeriodGranularity(
null, new Period("P1M2D"),
DateTimeZone.forID("America/Los_Angeles")); null,
assertSame( DateTimeZone.forID("America/Los_Angeles")
Lists.newArrayList( );
new DateTime("1970-01-01T00:00:00.000-08:00"), assertSame(
new DateTime("2011-12-12T00:00:00.000-08:00"), Lists.newArrayList(
new DateTime("2012-01-14T00:00:00.000-08:00"), new DateTime("1970-01-01T00:00:00.000-08:00"),
new DateTime("2012-02-16T00: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"),
Lists.newArrayList( new DateTime("2012-02-16T00:00:00.000-08:00")
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()), Lists.newArrayList(
periodNoOrigin.truncate(new DateTime("2012-01-15T07:01:04.123-08:00").getMillis()), periodNoOrigin.truncate(new DateTime("1970-01-01T05:02:04.123-08:00").getMillis()),
periodNoOrigin.truncate(new DateTime("2012-02-16T00:00:00.000-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 @Test
public void testCompoundPeriodMillisTruncate() throws Exception 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"), final DateTime origin = new DateTime("2012-01-02T05:00:00.000-08:00");
origin, QueryGranularity periodOrigin = new PeriodGranularity(
DateTimeZone.forID("America/Los_Angeles")); new Period("PT12H5M"),
assertSame( origin,
Lists.newArrayList( DateTimeZone.UTC
new DateTime("2012-01-01T04:50:00.000-08:00"), );
new DateTime("2012-01-02T05:00:00.000-08:00"), assertSame(
new DateTime("2012-01-02T17:05:00.000-08:00"), Lists.newArrayList(
new DateTime("2012-02-03T22:25:00.000-08:00") new DateTime("2012-01-01T04:50:00.000-08:00"),
), new DateTime("2012-01-02T05:00:00.000-08:00"),
Lists.newArrayList( new DateTime("2012-01-02T17:05:00.000-08:00"),
periodOrigin.truncate(new DateTime("2012-01-01T05:00:04.123-08:00").getMillis()), new DateTime("2012-02-03T22:25:00.000-08:00")
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()), Lists.newArrayList(
periodOrigin.truncate(new DateTime("2012-02-03T22:25:00.000-08:00").getMillis()) 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 @Test
@ -524,7 +557,7 @@ public class QueryGranularityTest
while (actualIter.hasNext() && expectedIter.hasNext()) { while (actualIter.hasNext() && expectedIter.hasNext()) {
long a = actualIter.next().longValue(); 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("actualIter not exhausted!?", actualIter.hasNext());
Assert.assertFalse("expectedIter not exhausted!?", expectedIter.hasNext()); Assert.assertFalse("expectedIter not exhausted!?", expectedIter.hasNext());