|  | @@ -23,6 +23,9 @@ import org.elasticsearch.common.rounding.TimeZoneRounding.TimeIntervalRounding;
 | 
	
		
			
				|  |  |  import org.elasticsearch.common.rounding.TimeZoneRounding.TimeUnitRounding;
 | 
	
		
			
				|  |  |  import org.elasticsearch.common.unit.TimeValue;
 | 
	
		
			
				|  |  |  import org.elasticsearch.test.ESTestCase;
 | 
	
		
			
				|  |  | +import org.hamcrest.Description;
 | 
	
		
			
				|  |  | +import org.hamcrest.Matcher;
 | 
	
		
			
				|  |  | +import org.hamcrest.TypeSafeMatcher;
 | 
	
		
			
				|  |  |  import org.joda.time.DateTime;
 | 
	
		
			
				|  |  |  import org.joda.time.DateTimeConstants;
 | 
	
		
			
				|  |  |  import org.joda.time.DateTimeZone;
 | 
	
	
		
			
				|  | @@ -38,67 +41,70 @@ import static org.hamcrest.Matchers.lessThanOrEqualTo;
 | 
	
		
			
				|  |  |  /**
 | 
	
		
			
				|  |  |   */
 | 
	
		
			
				|  |  |  public class TimeZoneRoundingTests extends ESTestCase {
 | 
	
		
			
				|  |  | -    final static DateTimeZone JERUSALEM_TIMEZONE = DateTimeZone.forID("Asia/Jerusalem");
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      public void testUTCTimeUnitRounding() {
 | 
	
		
			
				|  |  |          Rounding tzRounding = TimeZoneRounding.builder(DateTimeUnit.MONTH_OF_YEAR).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(utc("2009-02-03T01:01:01")), equalTo(utc("2009-02-01T00:00:00.000Z")));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.nextRoundingValue(utc("2009-02-01T00:00:00.000Z")), equalTo(utc("2009-03-01T00:00:00.000Z")));
 | 
	
		
			
				|  |  | +        DateTimeZone tz = DateTimeZone.UTC;
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2009-02-03T01:01:01")), isDate(time("2009-02-01T00:00:00.000Z"), tz));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.nextRoundingValue(time("2009-02-01T00:00:00.000Z")), isDate(time("2009-03-01T00:00:00.000Z"), tz));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          tzRounding = TimeZoneRounding.builder(DateTimeUnit.WEEK_OF_WEEKYEAR).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(utc("2012-01-10T01:01:01")), equalTo(utc("2012-01-09T00:00:00.000Z")));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.nextRoundingValue(utc("2012-01-09T00:00:00.000Z")), equalTo(utc("2012-01-16T00:00:00.000Z")));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2012-01-10T01:01:01")), isDate(time("2012-01-09T00:00:00.000Z"), tz));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.nextRoundingValue(time("2012-01-09T00:00:00.000Z")), isDate(time("2012-01-16T00:00:00.000Z"), tz));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          tzRounding = TimeZoneRounding.builder(DateTimeUnit.WEEK_OF_WEEKYEAR).offset(-TimeValue.timeValueHours(24).millis()).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(utc("2012-01-10T01:01:01")), equalTo(utc("2012-01-08T00:00:00.000Z")));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.nextRoundingValue(utc("2012-01-08T00:00:00.000Z")), equalTo(utc("2012-01-15T00:00:00.000Z")));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2012-01-10T01:01:01")), isDate(time("2012-01-08T00:00:00.000Z"), tz));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.nextRoundingValue(time("2012-01-08T00:00:00.000Z")), isDate(time("2012-01-15T00:00:00.000Z"), tz));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      public void testUTCIntervalRounding() {
 | 
	
		
			
				|  |  |          Rounding tzRounding = TimeZoneRounding.builder(TimeValue.timeValueHours(12)).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(utc("2009-02-03T01:01:01")), equalTo(utc("2009-02-03T00:00:00.000Z")));
 | 
	
		
			
				|  |  | -        long roundKey = tzRounding.roundKey(utc("2009-02-03T01:01:01"));
 | 
	
		
			
				|  |  | -        assertThat(roundKey, equalTo(tzRounding.roundKey(utc("2009-02-03T00:00:00.000Z"))));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.valueForKey(roundKey), equalTo(utc("2009-02-03T00:00:00.000Z")));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.nextRoundingValue(utc("2009-02-03T00:00:00.000Z")), equalTo(utc("2009-02-03T12:00:00.000Z")));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(utc("2009-02-03T13:01:01")), equalTo(utc("2009-02-03T12:00:00.000Z")));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.nextRoundingValue(utc("2009-02-03T12:00:00.000Z")), equalTo(utc("2009-02-04T00:00:00.000Z")));
 | 
	
		
			
				|  |  | +        DateTimeZone tz = DateTimeZone.UTC;
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2009-02-03T01:01:01")), isDate(time("2009-02-03T00:00:00.000Z"), tz));
 | 
	
		
			
				|  |  | +        long roundKey = tzRounding.roundKey(time("2009-02-03T01:01:01"));
 | 
	
		
			
				|  |  | +        assertThat(roundKey, isDate(tzRounding.roundKey(time("2009-02-03T00:00:00.000Z")), tz));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.valueForKey(roundKey), isDate(time("2009-02-03T00:00:00.000Z"), tz));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.nextRoundingValue(time("2009-02-03T00:00:00.000Z")), isDate(time("2009-02-03T12:00:00.000Z"), tz));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2009-02-03T13:01:01")), isDate(time("2009-02-03T12:00:00.000Z"), tz));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.nextRoundingValue(time("2009-02-03T12:00:00.000Z")), isDate(time("2009-02-04T00:00:00.000Z"), tz));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          tzRounding = TimeZoneRounding.builder(TimeValue.timeValueHours(48)).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(utc("2009-02-03T01:01:01")), equalTo(utc("2009-02-03T00:00:00.000Z")));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.nextRoundingValue(utc("2009-02-03T00:00:00.000Z")), equalTo(utc("2009-02-05T00:00:00.000Z")));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(utc("2009-02-05T13:01:01")), equalTo(utc("2009-02-05T00:00:00.000Z")));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.nextRoundingValue(utc("2009-02-05T00:00:00.000Z")), equalTo(utc("2009-02-07T00:00:00.000Z")));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2009-02-03T01:01:01")), isDate(time("2009-02-03T00:00:00.000Z"), tz));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.nextRoundingValue(time("2009-02-03T00:00:00.000Z")), isDate(time("2009-02-05T00:00:00.000Z"), tz));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2009-02-05T13:01:01")), isDate(time("2009-02-05T00:00:00.000Z"), tz));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.nextRoundingValue(time("2009-02-05T00:00:00.000Z")), isDate(time("2009-02-07T00:00:00.000Z"), tz));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * test TimeIntervalTimeZoneRounding, (interval < 12h) with time zone shift
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      public void testTimeIntervalTimeZoneRounding() {
 | 
	
		
			
				|  |  | -        Rounding tzRounding = TimeZoneRounding.builder(TimeValue.timeValueHours(6)).timeZone(DateTimeZone.forOffsetHours(-1)).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(utc("2009-02-03T00:01:01")), equalTo(utc("2009-02-02T19:00:00.000Z")));
 | 
	
		
			
				|  |  | -        long roundKey = tzRounding.roundKey(utc("2009-02-03T00:01:01"));
 | 
	
		
			
				|  |  | -        assertThat(roundKey, equalTo(tzRounding.roundKey(utc("2009-02-02T19:00:00.000Z"))));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.valueForKey(roundKey), equalTo(utc("2009-02-02T19:00:00.000Z")));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.nextRoundingValue(utc("2009-02-02T19:00:00.000Z")), equalTo(utc("2009-02-03T01:00:00.000Z")));
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(utc("2009-02-03T13:01:01")), equalTo(utc("2009-02-03T13:00:00.000Z")));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.nextRoundingValue(utc("2009-02-03T13:00:00.000Z")), equalTo(utc("2009-02-03T19:00:00.000Z")));
 | 
	
		
			
				|  |  | +        DateTimeZone tz = DateTimeZone.forOffsetHours(-1);
 | 
	
		
			
				|  |  | +        Rounding tzRounding = TimeZoneRounding.builder(TimeValue.timeValueHours(6)).timeZone(tz).build();
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2009-02-03T00:01:01")), isDate(time("2009-02-02T19:00:00.000Z"), tz));
 | 
	
		
			
				|  |  | +        long roundKey = tzRounding.roundKey(time("2009-02-03T00:01:01"));
 | 
	
		
			
				|  |  | +        assertThat(roundKey, equalTo(tzRounding.roundKey(time("2009-02-02T19:00:00.000Z"))));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.valueForKey(roundKey), isDate(time("2009-02-02T19:00:00.000Z"), tz));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.nextRoundingValue(time("2009-02-02T19:00:00.000Z")), isDate(time("2009-02-03T01:00:00.000Z"), tz));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2009-02-03T13:01:01")), isDate(time("2009-02-03T13:00:00.000Z"), tz));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.nextRoundingValue(time("2009-02-03T13:00:00.000Z")), isDate(time("2009-02-03T19:00:00.000Z"), tz));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * test DayIntervalTimeZoneRounding, (interval >= 12h) with time zone shift
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      public void testDayIntervalTimeZoneRounding() {
 | 
	
		
			
				|  |  | -        Rounding tzRounding = TimeZoneRounding.builder(TimeValue.timeValueHours(12)).timeZone(DateTimeZone.forOffsetHours(-8)).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(utc("2009-02-03T00:01:01")), equalTo(utc("2009-02-02T20:00:00.000Z")));
 | 
	
		
			
				|  |  | -        long roundKey = tzRounding.roundKey(utc("2009-02-03T00:01:01"));
 | 
	
		
			
				|  |  | -        assertThat(roundKey, equalTo(tzRounding.roundKey(utc("2009-02-02T20:00:00.000Z"))));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.valueForKey(roundKey), equalTo(utc("2009-02-02T20:00:00.000Z")));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.nextRoundingValue(utc("2009-02-02T20:00:00.000Z")), equalTo(utc("2009-02-03T08:00:00.000Z")));
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(utc("2009-02-03T13:01:01")), equalTo(utc("2009-02-03T08:00:00.000Z")));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.nextRoundingValue(utc("2009-02-03T08:00:00.000Z")), equalTo(utc("2009-02-03T20:00:00.000Z")));
 | 
	
		
			
				|  |  | +        DateTimeZone tz = DateTimeZone.forOffsetHours(-8);
 | 
	
		
			
				|  |  | +        Rounding tzRounding = TimeZoneRounding.builder(TimeValue.timeValueHours(12)).timeZone(tz).build();
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2009-02-03T00:01:01")), isDate(time("2009-02-02T20:00:00.000Z"), tz));
 | 
	
		
			
				|  |  | +        long roundKey = tzRounding.roundKey(time("2009-02-03T00:01:01"));
 | 
	
		
			
				|  |  | +        assertThat(roundKey, isDate(tzRounding.roundKey(time("2009-02-02T20:00:00.000Z")), tz));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.valueForKey(roundKey), isDate(time("2009-02-02T20:00:00.000Z"), tz));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.nextRoundingValue(time("2009-02-02T20:00:00.000Z")), isDate(time("2009-02-03T08:00:00.000Z"), tz));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2009-02-03T13:01:01")), isDate(time("2009-02-03T08:00:00.000Z"), tz));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.nextRoundingValue(time("2009-02-03T08:00:00.000Z")), isDate(time("2009-02-03T20:00:00.000Z"), tz));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      public void testDayTimeZoneRounding() {
 | 
	
	
		
			
				|  | @@ -109,106 +115,72 @@ public class TimeZoneRoundingTests extends ESTestCase {
 | 
	
		
			
				|  |  |          assertThat(tzRounding.nextRoundingValue(0L - TimeValue.timeValueHours(24 + timezoneOffset).millis()), equalTo(0L - TimeValue
 | 
	
		
			
				|  |  |                  .timeValueHours(timezoneOffset).millis()));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        tzRounding = TimeZoneRounding.builder(DateTimeUnit.DAY_OF_MONTH).timeZone(DateTimeZone.forID("-08:00")).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(utc("2012-04-01T04:15:30Z")), equalTo(utc("2012-03-31T08:00:00Z")));
 | 
	
		
			
				|  |  | -        assertThat(toUTCDateString(tzRounding.nextRoundingValue(utc("2012-03-31T08:00:00Z"))),
 | 
	
		
			
				|  |  | -                equalTo(toUTCDateString(utc("2012-04-01T08:0:00Z"))));
 | 
	
		
			
				|  |  | +        DateTimeZone tz = DateTimeZone.forID("-08:00");
 | 
	
		
			
				|  |  | +        tzRounding = TimeZoneRounding.builder(DateTimeUnit.DAY_OF_MONTH).timeZone(tz).build();
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2012-04-01T04:15:30Z")), isDate(time("2012-03-31T08:00:00Z"), tz));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        tzRounding = TimeZoneRounding.builder(DateTimeUnit.MONTH_OF_YEAR).timeZone(DateTimeZone.forID("-08:00")).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(utc("2012-04-01T04:15:30Z")), equalTo(utc("2012-03-01T08:00:00Z")));
 | 
	
		
			
				|  |  | -        assertThat(toUTCDateString(tzRounding.nextRoundingValue(utc("2012-03-01T08:00:00Z"))),
 | 
	
		
			
				|  |  | -                equalTo(toUTCDateString(utc("2012-04-01T08:0:00Z"))));
 | 
	
		
			
				|  |  | +        tzRounding = TimeZoneRounding.builder(DateTimeUnit.MONTH_OF_YEAR).timeZone(tz).build();
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2012-04-01T04:15:30Z")), equalTo(time("2012-03-01T08:00:00Z")));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // date in Feb-3rd, but still in Feb-2nd in -02:00 timezone
 | 
	
		
			
				|  |  | -        tzRounding = TimeZoneRounding.builder(DateTimeUnit.DAY_OF_MONTH).timeZone(DateTimeZone.forID("-02:00")).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(utc("2009-02-03T01:01:01")), equalTo(utc("2009-02-02T02:00:00")));
 | 
	
		
			
				|  |  | -        long roundKey = tzRounding.roundKey(utc("2009-02-03T01:01:01"));
 | 
	
		
			
				|  |  | -        assertThat(roundKey, equalTo(tzRounding.roundKey(utc("2009-02-02T02:00:00.000Z"))));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.valueForKey(roundKey), equalTo(utc("2009-02-02T02:00:00.000Z")));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.nextRoundingValue(utc("2009-02-02T02:00:00")), equalTo(utc("2009-02-03T02:00:00")));
 | 
	
		
			
				|  |  | +        tz = DateTimeZone.forID("-02:00");
 | 
	
		
			
				|  |  | +        tzRounding = TimeZoneRounding.builder(DateTimeUnit.DAY_OF_MONTH).timeZone(tz).build();
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2009-02-03T01:01:01")), isDate(time("2009-02-02T02:00:00"), tz));
 | 
	
		
			
				|  |  | +        long roundKey = tzRounding.roundKey(time("2009-02-03T01:01:01"));
 | 
	
		
			
				|  |  | +        assertThat(roundKey, isDate(tzRounding.roundKey(time("2009-02-02T02:00:00.000Z")), tz));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.valueForKey(roundKey), isDate(time("2009-02-02T02:00:00.000Z"), tz));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.nextRoundingValue(time("2009-02-02T02:00:00")), isDate(time("2009-02-03T02:00:00"), tz));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // date in Feb-3rd, also in -02:00 timezone
 | 
	
		
			
				|  |  | -        tzRounding = TimeZoneRounding.builder(DateTimeUnit.DAY_OF_MONTH).timeZone(DateTimeZone.forID("-02:00")).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(utc("2009-02-03T02:01:01")), equalTo(utc("2009-02-03T02:00:00")));
 | 
	
		
			
				|  |  | -        roundKey = tzRounding.roundKey(utc("2009-02-03T02:01:01"));
 | 
	
		
			
				|  |  | -        assertThat(roundKey, equalTo(tzRounding.roundKey(utc("2009-02-03T02:00:00.000Z"))));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.valueForKey(roundKey), equalTo(utc("2009-02-03T02:00:00.000Z")));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.nextRoundingValue(utc("2009-02-03T02:00:00")), equalTo(utc("2009-02-04T02:00:00")));
 | 
	
		
			
				|  |  | +        tzRounding = TimeZoneRounding.builder(DateTimeUnit.DAY_OF_MONTH).timeZone(tz).build();
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2009-02-03T02:01:01")), isDate(time("2009-02-03T02:00:00"), tz));
 | 
	
		
			
				|  |  | +        roundKey = tzRounding.roundKey(time("2009-02-03T02:01:01"));
 | 
	
		
			
				|  |  | +        assertThat(roundKey, isDate(tzRounding.roundKey(time("2009-02-03T02:00:00.000Z")), tz));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.valueForKey(roundKey), isDate(time("2009-02-03T02:00:00.000Z"), tz));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.nextRoundingValue(time("2009-02-03T02:00:00")), isDate(time("2009-02-04T02:00:00"), tz));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      public void testTimeTimeZoneRounding() {
 | 
	
		
			
				|  |  |          // hour unit
 | 
	
		
			
				|  |  | -        Rounding tzRounding = TimeZoneRounding.builder(DateTimeUnit.HOUR_OF_DAY).timeZone(DateTimeZone.forOffsetHours(-2)).build();
 | 
	
		
			
				|  |  | +        DateTimeZone tz = DateTimeZone.forOffsetHours(-2);
 | 
	
		
			
				|  |  | +        Rounding tzRounding = TimeZoneRounding.builder(DateTimeUnit.HOUR_OF_DAY).timeZone(tz).build();
 | 
	
		
			
				|  |  |          assertThat(tzRounding.round(0), equalTo(0L));
 | 
	
		
			
				|  |  |          assertThat(tzRounding.nextRoundingValue(0L), equalTo(TimeValue.timeValueHours(1L).getMillis()));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        tzRounding = TimeZoneRounding.builder(DateTimeUnit.HOUR_OF_DAY).timeZone(DateTimeZone.forOffsetHours(-2)).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(utc("2009-02-03T01:01:01")), equalTo(utc("2009-02-03T01:00:00")));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.nextRoundingValue(utc("2009-02-03T01:00:00")), equalTo(utc("2009-02-03T02:00:00")));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2009-02-03T01:01:01")), isDate(time("2009-02-03T01:00:00"), tz));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.nextRoundingValue(time("2009-02-03T01:00:00")), isDate(time("2009-02-03T02:00:00"), tz));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      public void testTimeUnitRoundingDST() {
 | 
	
		
			
				|  |  |          Rounding tzRounding;
 | 
	
		
			
				|  |  |          // testing savings to non savings switch
 | 
	
		
			
				|  |  | -        tzRounding = TimeZoneRounding.builder(DateTimeUnit.HOUR_OF_DAY).timeZone(DateTimeZone.forID("UTC")).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(time("2014-10-26T01:01:01", DateTimeZone.forOffsetHours(2))),  // CEST = UTC+2
 | 
	
		
			
				|  |  | -                equalTo(time("2014-10-26T01:00:00", DateTimeZone.forOffsetHours(2))));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.nextRoundingValue(time("2014-10-26T01:00:00", DateTimeZone.forOffsetHours(2))),
 | 
	
		
			
				|  |  | -                equalTo(time("2014-10-26T02:00:00", DateTimeZone.forOffsetHours(2))));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.nextRoundingValue(time("2014-10-26T02:00:00", DateTimeZone.forOffsetHours(2))),
 | 
	
		
			
				|  |  | -                equalTo(time("2014-10-26T03:00:00", DateTimeZone.forOffsetHours(2))));
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        tzRounding = TimeZoneRounding.builder(DateTimeUnit.HOUR_OF_DAY).timeZone(DateTimeZone.forID("CET")).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(time("2014-10-26T01:01:01", DateTimeZone.forOffsetHours(2))),  // CEST = UTC+2
 | 
	
		
			
				|  |  | -                equalTo(time("2014-10-26T01:00:00", DateTimeZone.forOffsetHours(2))));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.nextRoundingValue(time("2014-10-26T01:00:00", DateTimeZone.forOffsetHours(2))),
 | 
	
		
			
				|  |  | -                equalTo(time("2014-10-26T02:00:00", DateTimeZone.forOffsetHours(2))));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.nextRoundingValue(time("2014-10-26T02:00:00", DateTimeZone.forOffsetHours(2))),
 | 
	
		
			
				|  |  | -                equalTo(time("2014-10-26T03:00:00", DateTimeZone.forOffsetHours(2))));
 | 
	
		
			
				|  |  | +        DateTimeZone cet = DateTimeZone.forID("CET");
 | 
	
		
			
				|  |  | +        tzRounding = TimeZoneRounding.builder(DateTimeUnit.HOUR_OF_DAY).timeZone(cet).build();
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2014-10-26T01:01:01", cet)), isDate(time("2014-10-26T01:00:00+02:00"), cet));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.nextRoundingValue(time("2014-10-26T01:00:00", cet)),isDate(time("2014-10-26T02:00:00+02:00"), cet));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.nextRoundingValue(time("2014-10-26T02:00:00", cet)), isDate(time("2014-10-26T02:00:00+01:00"), cet));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // testing non savings to savings switch
 | 
	
		
			
				|  |  | -        tzRounding = TimeZoneRounding.builder(DateTimeUnit.HOUR_OF_DAY).timeZone(DateTimeZone.forID("UTC")).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(time("2014-03-30T01:01:01", DateTimeZone.forOffsetHours(1))),  // CET = UTC+1
 | 
	
		
			
				|  |  | -                equalTo(time("2014-03-30T01:00:00", DateTimeZone.forOffsetHours(1))));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.nextRoundingValue(time("2014-03-30T01:00:00", DateTimeZone.forOffsetHours(1))),
 | 
	
		
			
				|  |  | -                equalTo(time("2014-03-30T02:00:00", DateTimeZone.forOffsetHours(1))));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.nextRoundingValue(time("2014-03-30T02:00:00", DateTimeZone.forOffsetHours(1))),
 | 
	
		
			
				|  |  | -                equalTo(time("2014-03-30T03:00:00", DateTimeZone.forOffsetHours(1))));
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        tzRounding = TimeZoneRounding.builder(DateTimeUnit.HOUR_OF_DAY).timeZone(DateTimeZone.forID("CET")).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(time("2014-03-30T01:01:01", DateTimeZone.forOffsetHours(1))),  // CET = UTC+1
 | 
	
		
			
				|  |  | -                equalTo(time("2014-03-30T01:00:00", DateTimeZone.forOffsetHours(1))));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.nextRoundingValue(time("2014-03-30T01:00:00", DateTimeZone.forOffsetHours(1))),
 | 
	
		
			
				|  |  | -                equalTo(time("2014-03-30T02:00:00", DateTimeZone.forOffsetHours(1))));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.nextRoundingValue(time("2014-03-30T02:00:00", DateTimeZone.forOffsetHours(1))),
 | 
	
		
			
				|  |  | -                equalTo(time("2014-03-30T03:00:00", DateTimeZone.forOffsetHours(1))));
 | 
	
		
			
				|  |  | +        tzRounding = TimeZoneRounding.builder(DateTimeUnit.HOUR_OF_DAY).timeZone(cet).build();
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2014-03-30T01:01:01", cet)), isDate(time("2014-03-30T01:00:00+01:00"), cet));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.nextRoundingValue(time("2014-03-30T01:00:00", cet)), isDate(time("2014-03-30T03:00:00", cet), cet));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.nextRoundingValue(time("2014-03-30T03:00:00", cet)), isDate(time("2014-03-30T04:00:00", cet), cet));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // testing non savings to savings switch (America/Chicago)
 | 
	
		
			
				|  |  | -        tzRounding = TimeZoneRounding.builder(DateTimeUnit.HOUR_OF_DAY).timeZone(DateTimeZone.forID("UTC")).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(time("2014-03-09T03:01:01", DateTimeZone.forID("America/Chicago"))),
 | 
	
		
			
				|  |  | -                equalTo(time("2014-03-09T03:00:00", DateTimeZone.forID("America/Chicago"))));
 | 
	
		
			
				|  |  | +        DateTimeZone chg = DateTimeZone.forID("America/Chicago");
 | 
	
		
			
				|  |  | +        Rounding tzRounding_utc = TimeZoneRounding.builder(DateTimeUnit.HOUR_OF_DAY).timeZone(DateTimeZone.UTC).build();
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2014-03-09T03:01:01", chg)), isDate(time("2014-03-09T03:00:00", chg), chg));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        tzRounding = TimeZoneRounding.builder(DateTimeUnit.HOUR_OF_DAY).timeZone(DateTimeZone.forID("America/Chicago")).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(time("2014-03-09T03:01:01", DateTimeZone.forID("America/Chicago"))),
 | 
	
		
			
				|  |  | -                equalTo(time("2014-03-09T03:00:00", DateTimeZone.forID("America/Chicago"))));
 | 
	
		
			
				|  |  | +        Rounding tzRounding_chg = TimeZoneRounding.builder(DateTimeUnit.HOUR_OF_DAY).timeZone(chg).build();
 | 
	
		
			
				|  |  | +        assertThat(tzRounding_chg.round(time("2014-03-09T03:01:01", chg)), isDate(time("2014-03-09T03:00:00", chg), chg));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // testing savings to non savings switch 2013 (America/Chicago)
 | 
	
		
			
				|  |  | -        tzRounding = TimeZoneRounding.builder(DateTimeUnit.HOUR_OF_DAY).timeZone(DateTimeZone.forID("UTC")).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(time("2013-11-03T06:01:01", DateTimeZone.forID("America/Chicago"))),
 | 
	
		
			
				|  |  | -                equalTo(time("2013-11-03T06:00:00", DateTimeZone.forID("America/Chicago"))));
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        tzRounding = TimeZoneRounding.builder(DateTimeUnit.HOUR_OF_DAY).timeZone(DateTimeZone.forID("America/Chicago")).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(time("2013-11-03T06:01:01", DateTimeZone.forID("America/Chicago"))),
 | 
	
		
			
				|  |  | -                equalTo(time("2013-11-03T06:00:00", DateTimeZone.forID("America/Chicago"))));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding_utc.round(time("2013-11-03T06:01:01", chg)), isDate(time("2013-11-03T06:00:00", chg), chg));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding_chg.round(time("2013-11-03T06:01:01", chg)), isDate(time("2013-11-03T06:00:00", chg), chg));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // testing savings to non savings switch 2014 (America/Chicago)
 | 
	
		
			
				|  |  | -        tzRounding = TimeZoneRounding.builder(DateTimeUnit.HOUR_OF_DAY).timeZone(DateTimeZone.forID("UTC")).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(time("2014-11-02T06:01:01", DateTimeZone.forID("America/Chicago"))),
 | 
	
		
			
				|  |  | -                equalTo(time("2014-11-02T06:00:00", DateTimeZone.forID("America/Chicago"))));
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        tzRounding = TimeZoneRounding.builder(DateTimeUnit.HOUR_OF_DAY).timeZone(DateTimeZone.forID("America/Chicago")).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(time("2014-11-02T06:01:01", DateTimeZone.forID("America/Chicago"))),
 | 
	
		
			
				|  |  | -                equalTo(time("2014-11-02T06:00:00", DateTimeZone.forID("America/Chicago"))));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding_utc.round(time("2014-11-02T06:01:01", chg)), isDate(time("2014-11-02T06:00:00", chg), chg));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding_chg.round(time("2014-11-02T06:01:01", chg)), isDate(time("2014-11-02T06:00:00", chg), chg));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 | 
	
	
		
			
				|  | @@ -217,28 +189,28 @@ public class TimeZoneRoundingTests extends ESTestCase {
 | 
	
		
			
				|  |  |       * test dates that are exactly on or close to offset changes (e.g. DST) in the chosen time zone.
 | 
	
		
			
				|  |  |       *
 | 
	
		
			
				|  |  |       * It rounds the test date down and up and performs various checks on the rounding unit interval that is
 | 
	
		
			
				|  |  | -     * defined by this. Assumptions tested are described in {@link #assertInterval(long, long, long, TimeZoneRounding)}
 | 
	
		
			
				|  |  | +     * defined by this. Assumptions tested are described in {@link #assertInterval(long, long, long, TimeZoneRounding, DateTimeZone)}
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      public void testTimeZoneRoundingRandom() {
 | 
	
		
			
				|  |  |          for (int i = 0; i < 1000; ++i) {
 | 
	
		
			
				|  |  |              DateTimeUnit timeUnit = randomTimeUnit();
 | 
	
		
			
				|  |  | -            DateTimeZone timezone = randomDateTimeZone();
 | 
	
		
			
				|  |  | -            TimeZoneRounding rounding = new TimeZoneRounding.TimeUnitRounding(timeUnit, timezone);
 | 
	
		
			
				|  |  | +            DateTimeZone tz = randomDateTimeZone();
 | 
	
		
			
				|  |  | +            TimeZoneRounding rounding = new TimeZoneRounding.TimeUnitRounding(timeUnit, tz);
 | 
	
		
			
				|  |  |              long date = Math.abs(randomLong() % (2 * (long) 10e11)); // 1970-01-01T00:00:00Z - 2033-05-18T05:33:20.000+02:00
 | 
	
		
			
				|  |  | -            long unitMillis = timeUnit.field(timezone).getDurationField().getUnitMillis();
 | 
	
		
			
				|  |  | +            long unitMillis = timeUnit.field(tz).getDurationField().getUnitMillis();
 | 
	
		
			
				|  |  |              if (randomBoolean()) {
 | 
	
		
			
				|  |  | -                nastyDate(date, timezone, unitMillis);
 | 
	
		
			
				|  |  | +                nastyDate(date, tz, unitMillis);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              final long roundedDate = rounding.round(date);
 | 
	
		
			
				|  |  |              final long nextRoundingValue = rounding.nextRoundingValue(roundedDate);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            assertInterval(roundedDate, date, nextRoundingValue, rounding);
 | 
	
		
			
				|  |  | +            assertInterval(roundedDate, date, nextRoundingValue, rounding, tz);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              // check correct unit interval width for units smaller than a day, they should be fixed size except for transitions
 | 
	
		
			
				|  |  |              if (unitMillis <= DateTimeConstants.MILLIS_PER_DAY) {
 | 
	
		
			
				|  |  |                  // if the interval defined didn't cross timezone offset transition, it should cover unitMillis width
 | 
	
		
			
				|  |  | -                if (timezone.getOffset(roundedDate - 1) == timezone.getOffset(nextRoundingValue + 1)) {
 | 
	
		
			
				|  |  | -                    assertThat("unit interval width not as expected for [" + timeUnit + "], [" + timezone + "] at "
 | 
	
		
			
				|  |  | +                if (tz.getOffset(roundedDate - 1) == tz.getOffset(nextRoundingValue + 1)) {
 | 
	
		
			
				|  |  | +                    assertThat("unit interval width not as expected for [" + timeUnit + "], [" + tz + "] at "
 | 
	
		
			
				|  |  |                              + new DateTime(roundedDate), nextRoundingValue - roundedDate, equalTo(unitMillis));
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |              }
 | 
	
	
		
			
				|  | @@ -264,17 +236,18 @@ public class TimeZoneRoundingTests extends ESTestCase {
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      public void testTimeIntervalCET_DST_End() {
 | 
	
		
			
				|  |  |          long interval = TimeUnit.MINUTES.toMillis(20);
 | 
	
		
			
				|  |  | -        TimeZoneRounding rounding = new TimeIntervalRounding(interval, DateTimeZone.forID("CET"));
 | 
	
		
			
				|  |  | +        DateTimeZone tz = DateTimeZone.forID("CET");
 | 
	
		
			
				|  |  | +        TimeZoneRounding rounding = new TimeIntervalRounding(interval, tz);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        assertThat(rounding.round(time("2015-10-25T01:55:00+02:00")), equalTo(time("2015-10-25T01:40:00+02:00")));
 | 
	
		
			
				|  |  | -        assertThat(rounding.round(time("2015-10-25T02:15:00+02:00")), equalTo(time("2015-10-25T02:00:00+02:00")));
 | 
	
		
			
				|  |  | -        assertThat(rounding.round(time("2015-10-25T02:35:00+02:00")), equalTo(time("2015-10-25T02:20:00+02:00")));
 | 
	
		
			
				|  |  | -        assertThat(rounding.round(time("2015-10-25T02:55:00+02:00")), equalTo(time("2015-10-25T02:40:00+02:00")));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("2015-10-25T01:55:00+02:00")), isDate(time("2015-10-25T01:40:00+02:00"), tz));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("2015-10-25T02:15:00+02:00")), isDate(time("2015-10-25T02:00:00+02:00"), tz));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("2015-10-25T02:35:00+02:00")), isDate(time("2015-10-25T02:20:00+02:00"), tz));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("2015-10-25T02:55:00+02:00")), isDate(time("2015-10-25T02:40:00+02:00"), tz));
 | 
	
		
			
				|  |  |          // after DST shift
 | 
	
		
			
				|  |  | -        assertThat(rounding.round(time("2015-10-25T02:15:00+01:00")), equalTo(time("2015-10-25T02:00:00+01:00")));
 | 
	
		
			
				|  |  | -        assertThat(rounding.round(time("2015-10-25T02:35:00+01:00")), equalTo(time("2015-10-25T02:20:00+01:00")));
 | 
	
		
			
				|  |  | -        assertThat(rounding.round(time("2015-10-25T02:55:00+01:00")), equalTo(time("2015-10-25T02:40:00+01:00")));
 | 
	
		
			
				|  |  | -        assertThat(rounding.round(time("2015-10-25T03:15:00+01:00")), equalTo(time("2015-10-25T03:00:00+01:00")));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("2015-10-25T02:15:00+01:00")), isDate(time("2015-10-25T02:00:00+01:00"), tz));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("2015-10-25T02:35:00+01:00")), isDate(time("2015-10-25T02:20:00+01:00"), tz));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("2015-10-25T02:55:00+01:00")), isDate(time("2015-10-25T02:40:00+01:00"), tz));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("2015-10-25T03:15:00+01:00")), isDate(time("2015-10-25T03:00:00+01:00"), tz));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 | 
	
	
		
			
				|  | @@ -283,12 +256,13 @@ public class TimeZoneRoundingTests extends ESTestCase {
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      public void testTimeIntervalCET_DST_Start() {
 | 
	
		
			
				|  |  |          long interval = TimeUnit.MINUTES.toMillis(20);
 | 
	
		
			
				|  |  | -        TimeZoneRounding rounding = new TimeIntervalRounding(interval, DateTimeZone.forID("CET"));
 | 
	
		
			
				|  |  | +        DateTimeZone tz = DateTimeZone.forID("CET");
 | 
	
		
			
				|  |  | +        TimeZoneRounding rounding = new TimeIntervalRounding(interval, tz);
 | 
	
		
			
				|  |  |          // test DST start
 | 
	
		
			
				|  |  | -        assertThat(rounding.round(time("2016-03-27T01:55:00+01:00")), equalTo(time("2016-03-27T01:40:00+01:00")));
 | 
	
		
			
				|  |  | -        assertThat(rounding.round(time("2016-03-27T02:00:00+01:00")), equalTo(time("2016-03-27T03:00:00+02:00")));
 | 
	
		
			
				|  |  | -        assertThat(rounding.round(time("2016-03-27T03:15:00+02:00")), equalTo(time("2016-03-27T03:00:00+02:00")));
 | 
	
		
			
				|  |  | -        assertThat(rounding.round(time("2016-03-27T03:35:00+02:00")), equalTo(time("2016-03-27T03:20:00+02:00")));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("2016-03-27T01:55:00+01:00")), isDate(time("2016-03-27T01:40:00+01:00"), tz));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("2016-03-27T02:00:00+01:00")), isDate(time("2016-03-27T03:00:00+02:00"), tz));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("2016-03-27T03:15:00+02:00")), isDate(time("2016-03-27T03:00:00+02:00"), tz));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("2016-03-27T03:35:00+02:00")), isDate(time("2016-03-27T03:20:00+02:00"), tz));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 | 
	
	
		
			
				|  | @@ -299,13 +273,14 @@ public class TimeZoneRoundingTests extends ESTestCase {
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      public void testTimeInterval_Kathmandu_DST_Start() {
 | 
	
		
			
				|  |  |          long interval = TimeUnit.MINUTES.toMillis(20);
 | 
	
		
			
				|  |  | -        TimeZoneRounding rounding = new TimeIntervalRounding(interval, DateTimeZone.forID("Asia/Kathmandu"));
 | 
	
		
			
				|  |  | -        assertThat(rounding.round(time("1985-12-31T23:55:00+05:30")), equalTo(time("1985-12-31T23:40:00+05:30")));
 | 
	
		
			
				|  |  | -        assertThat(rounding.round(time("1986-01-01T00:16:00+05:45")), equalTo(time("1986-01-01T00:15:00+05:45")));
 | 
	
		
			
				|  |  | +        DateTimeZone tz = DateTimeZone.forID("Asia/Kathmandu");
 | 
	
		
			
				|  |  | +        TimeZoneRounding rounding = new TimeIntervalRounding(interval, tz);
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("1985-12-31T23:55:00+05:30")), isDate(time("1985-12-31T23:40:00+05:30"), tz));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("1986-01-01T00:16:00+05:45")), isDate(time("1986-01-01T00:15:00+05:45"), tz));
 | 
	
		
			
				|  |  |          assertThat(time("1986-01-01T00:15:00+05:45") - time("1985-12-31T23:40:00+05:30"), equalTo(TimeUnit.MINUTES.toMillis(20)));
 | 
	
		
			
				|  |  | -        assertThat(rounding.round(time("1986-01-01T00:26:00+05:45")), equalTo(time("1986-01-01T00:20:00+05:45")));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("1986-01-01T00:26:00+05:45")), isDate(time("1986-01-01T00:20:00+05:45"), tz));
 | 
	
		
			
				|  |  |          assertThat(time("1986-01-01T00:20:00+05:45") - time("1986-01-01T00:15:00+05:45"), equalTo(TimeUnit.MINUTES.toMillis(5)));
 | 
	
		
			
				|  |  | -        assertThat(rounding.round(time("1986-01-01T00:46:00+05:45")), equalTo(time("1986-01-01T00:40:00+05:45")));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("1986-01-01T00:46:00+05:45")), isDate(time("1986-01-01T00:40:00+05:45"), tz));
 | 
	
		
			
				|  |  |          assertThat(time("1986-01-01T00:40:00+05:45") - time("1986-01-01T00:20:00+05:45"), equalTo(TimeUnit.MINUTES.toMillis(20)));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -319,13 +294,29 @@ public class TimeZoneRoundingTests extends ESTestCase {
 | 
	
		
			
				|  |  |          long interval = TimeUnit.MINUTES.toMillis(14);
 | 
	
		
			
				|  |  |          TimeZoneRounding rounding = new TimeZoneRounding.TimeIntervalRounding(interval, tz);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        assertThat(rounding.round(time("2016-03-27T01:41:00+01:00")), equalTo(time("2016-03-27T01:30:00+01:00")));
 | 
	
		
			
				|  |  | -        assertThat(rounding.round(time("2016-03-27T01:51:00+01:00")), equalTo(time("2016-03-27T01:44:00+01:00")));
 | 
	
		
			
				|  |  | -        assertThat(rounding.round(time("2016-03-27T01:59:00+01:00")), equalTo(time("2016-03-27T01:58:00+01:00")));
 | 
	
		
			
				|  |  | -        assertThat(rounding.round(time("2016-03-27T03:05:00+02:00")), equalTo(time("2016-03-27T03:00:00+02:00")));
 | 
	
		
			
				|  |  | -        assertThat(rounding.round(time("2016-03-27T03:12:00+02:00")), equalTo(time("2016-03-27T03:08:00+02:00")));
 | 
	
		
			
				|  |  | -        assertThat(rounding.round(time("2016-03-27T03:25:00+02:00")), equalTo(time("2016-03-27T03:22:00+02:00")));
 | 
	
		
			
				|  |  | -        assertThat(rounding.round(time("2016-03-27T03:39:00+02:00")), equalTo(time("2016-03-27T03:36:00+02:00")));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("2016-03-27T01:41:00+01:00")), isDate(time("2016-03-27T01:30:00+01:00"), tz));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("2016-03-27T01:51:00+01:00")), isDate(time("2016-03-27T01:44:00+01:00"), tz));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("2016-03-27T01:59:00+01:00")), isDate(time("2016-03-27T01:58:00+01:00"), tz));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("2016-03-27T03:05:00+02:00")), isDate(time("2016-03-27T03:00:00+02:00"), tz));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("2016-03-27T03:12:00+02:00")), isDate(time("2016-03-27T03:08:00+02:00"), tz));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("2016-03-27T03:25:00+02:00")), isDate(time("2016-03-27T03:22:00+02:00"), tz));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("2016-03-27T03:39:00+02:00")), isDate(time("2016-03-27T03:36:00+02:00"), tz));
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * Test for half day rounding intervals scrossing DST.
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    public void testIntervalRounding_HalfDay_DST() {
 | 
	
		
			
				|  |  | +        DateTimeZone tz = DateTimeZone.forID("CET");
 | 
	
		
			
				|  |  | +        long interval = TimeUnit.HOURS.toMillis(12);
 | 
	
		
			
				|  |  | +        TimeZoneRounding rounding = new TimeZoneRounding.TimeIntervalRounding(interval, tz);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("2016-03-26T01:00:00+01:00")), isDate(time("2016-03-26T00:00:00+01:00"), tz));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("2016-03-26T13:00:00+01:00")), isDate(time("2016-03-26T12:00:00+01:00"), tz));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("2016-03-27T01:00:00+01:00")), isDate(time("2016-03-27T00:00:00+01:00"), tz));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("2016-03-27T13:00:00+02:00")), isDate(time("2016-03-27T12:00:00+02:00"), tz));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("2016-03-28T01:00:00+02:00")), isDate(time("2016-03-28T00:00:00+02:00"), tz));
 | 
	
		
			
				|  |  | +        assertThat(rounding.round(time("2016-03-28T13:00:00+02:00")), isDate(time("2016-03-28T12:00:00+02:00"), tz));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 | 
	
	
		
			
				|  | @@ -365,36 +356,39 @@ public class TimeZoneRoundingTests extends ESTestCase {
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      public void testAmbiguousHoursAfterDSTSwitch() {
 | 
	
		
			
				|  |  |          Rounding tzRounding;
 | 
	
		
			
				|  |  | -        tzRounding = TimeZoneRounding.builder(DateTimeUnit.HOUR_OF_DAY).timeZone(JERUSALEM_TIMEZONE).build();
 | 
	
		
			
				|  |  | -        // Both timestamps "2014-10-25T22:30:00Z" and "2014-10-25T23:30:00Z" are "2014-10-26T01:30:00" in local time because
 | 
	
		
			
				|  |  | -        // of DST switch between them. This test checks that they are both returned to their correct UTC time after rounding.
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(time("2014-10-25T22:30:00", DateTimeZone.UTC)), equalTo(time("2014-10-25T22:00:00", DateTimeZone.UTC)));
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(time("2014-10-25T23:30:00", DateTimeZone.UTC)), equalTo(time("2014-10-25T23:00:00", DateTimeZone.UTC)));
 | 
	
		
			
				|  |  | +        final DateTimeZone tz = DateTimeZone.forID("Asia/Jerusalem");
 | 
	
		
			
				|  |  | +        tzRounding = TimeZoneRounding.builder(DateTimeUnit.HOUR_OF_DAY).timeZone(tz).build();
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2014-10-26T00:30:00+03:00")), isDate(time("2014-10-26T00:00:00+03:00"), tz));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2014-10-26T01:30:00+03:00")), isDate(time("2014-10-26T01:00:00+03:00"), tz));
 | 
	
		
			
				|  |  | +        // the utc date for "2014-10-25T03:00:00+03:00" and "2014-10-25T03:00:00+02:00" is the same, local time turns back 1h here
 | 
	
		
			
				|  |  | +        assertThat(time("2014-10-26T03:00:00+03:00"), isDate(time("2014-10-26T02:00:00+02:00"), tz));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2014-10-26T01:30:00+02:00")), isDate(time("2014-10-26T01:00:00+02:00"), tz));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2014-10-26T02:30:00+02:00")), isDate(time("2014-10-26T02:00:00+02:00"), tz));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // Day interval
 | 
	
		
			
				|  |  | -        tzRounding = TimeZoneRounding.builder(DateTimeUnit.DAY_OF_MONTH).timeZone(JERUSALEM_TIMEZONE).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(time("2014-11-11T17:00:00", JERUSALEM_TIMEZONE)), equalTo(time("2014-11-11T00:00:00", JERUSALEM_TIMEZONE)));
 | 
	
		
			
				|  |  | +        tzRounding = TimeZoneRounding.builder(DateTimeUnit.DAY_OF_MONTH).timeZone(tz).build();
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2014-11-11T17:00:00", tz)), isDate(time("2014-11-11T00:00:00", tz), tz));
 | 
	
		
			
				|  |  |          // DST on
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(time("2014-08-11T17:00:00", JERUSALEM_TIMEZONE)), equalTo(time("2014-08-11T00:00:00", JERUSALEM_TIMEZONE)));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2014-08-11T17:00:00", tz)), isDate(time("2014-08-11T00:00:00", tz), tz));
 | 
	
		
			
				|  |  |          // Day of switching DST on -> off
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(time("2014-10-26T17:00:00", JERUSALEM_TIMEZONE)), equalTo(time("2014-10-26T00:00:00", JERUSALEM_TIMEZONE)));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2014-10-26T17:00:00", tz)), isDate(time("2014-10-26T00:00:00", tz), tz));
 | 
	
		
			
				|  |  |          // Day of switching DST off -> on
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(time("2015-03-27T17:00:00", JERUSALEM_TIMEZONE)), equalTo(time("2015-03-27T00:00:00", JERUSALEM_TIMEZONE)));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2015-03-27T17:00:00", tz)), isDate(time("2015-03-27T00:00:00", tz), tz));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // Month interval
 | 
	
		
			
				|  |  | -        tzRounding = TimeZoneRounding.builder(DateTimeUnit.MONTH_OF_YEAR).timeZone(JERUSALEM_TIMEZONE).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(time("2014-11-11T17:00:00", JERUSALEM_TIMEZONE)), equalTo(time("2014-11-01T00:00:00", JERUSALEM_TIMEZONE)));
 | 
	
		
			
				|  |  | +        tzRounding = TimeZoneRounding.builder(DateTimeUnit.MONTH_OF_YEAR).timeZone(tz).build();
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2014-11-11T17:00:00", tz)), isDate(time("2014-11-01T00:00:00", tz), tz));
 | 
	
		
			
				|  |  |          // DST on
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(time("2014-10-10T17:00:00", JERUSALEM_TIMEZONE)), equalTo(time("2014-10-01T00:00:00", JERUSALEM_TIMEZONE)));
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2014-10-10T17:00:00", tz)), isDate(time("2014-10-01T00:00:00", tz), tz));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // Year interval
 | 
	
		
			
				|  |  | -        tzRounding = TimeZoneRounding.builder(DateTimeUnit.YEAR_OF_CENTURY).timeZone(JERUSALEM_TIMEZONE).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(time("2014-11-11T17:00:00", JERUSALEM_TIMEZONE)), equalTo(time("2014-01-01T00:00:00", JERUSALEM_TIMEZONE)));
 | 
	
		
			
				|  |  | +        tzRounding = TimeZoneRounding.builder(DateTimeUnit.YEAR_OF_CENTURY).timeZone(tz).build();
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2014-11-11T17:00:00", tz)), isDate(time("2014-01-01T00:00:00", tz), tz));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // Two timestamps in same year and different timezone offset ("Double buckets" issue - #9491)
 | 
	
		
			
				|  |  | -        tzRounding = TimeZoneRounding.builder(DateTimeUnit.YEAR_OF_CENTURY).timeZone(JERUSALEM_TIMEZONE).build();
 | 
	
		
			
				|  |  | -        assertThat(tzRounding.round(time("2014-11-11T17:00:00", JERUSALEM_TIMEZONE)),
 | 
	
		
			
				|  |  | -                equalTo(tzRounding.round(time("2014-08-11T17:00:00", JERUSALEM_TIMEZONE))));
 | 
	
		
			
				|  |  | +        tzRounding = TimeZoneRounding.builder(DateTimeUnit.YEAR_OF_CENTURY).timeZone(tz).build();
 | 
	
		
			
				|  |  | +        assertThat(tzRounding.round(time("2014-11-11T17:00:00", tz)),
 | 
	
		
			
				|  |  | +                isDate(tzRounding.round(time("2014-08-11T17:00:00", tz)), tz));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 | 
	
	
		
			
				|  | @@ -417,20 +411,20 @@ public class TimeZoneRoundingTests extends ESTestCase {
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              // standard +/-1 hour DST transition, CET
 | 
	
		
			
				|  |  |              DateTimeUnit timeUnit = DateTimeUnit.HOUR_OF_DAY;
 | 
	
		
			
				|  |  | -            DateTimeZone timezone = DateTimeZone.forID("CET");
 | 
	
		
			
				|  |  | -            TimeZoneRounding rounding = new TimeZoneRounding.TimeUnitRounding(timeUnit, timezone);
 | 
	
		
			
				|  |  | +            DateTimeZone tz = DateTimeZone.forID("CET");
 | 
	
		
			
				|  |  | +            TimeZoneRounding rounding = new TimeZoneRounding.TimeUnitRounding(timeUnit, tz);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              // 29 Mar 2015 - Daylight Saving Time Started
 | 
	
		
			
				|  |  |              // at 02:00:00 clocks were turned forward 1 hour to 03:00:00
 | 
	
		
			
				|  |  | -            assertInterval(time("2015-03-29T00:00:00.000+01:00"), time("2015-03-29T01:00:00.000+01:00"), rounding, 60);
 | 
	
		
			
				|  |  | -            assertInterval(time("2015-03-29T01:00:00.000+01:00"), time("2015-03-29T03:00:00.000+02:00"), rounding, 60);
 | 
	
		
			
				|  |  | -            assertInterval(time("2015-03-29T03:00:00.000+02:00"), time("2015-03-29T04:00:00.000+02:00"), rounding, 60);
 | 
	
		
			
				|  |  | +            assertInterval(time("2015-03-29T00:00:00.000+01:00"), time("2015-03-29T01:00:00.000+01:00"), rounding, 60, tz);
 | 
	
		
			
				|  |  | +            assertInterval(time("2015-03-29T01:00:00.000+01:00"), time("2015-03-29T03:00:00.000+02:00"), rounding, 60, tz);
 | 
	
		
			
				|  |  | +            assertInterval(time("2015-03-29T03:00:00.000+02:00"), time("2015-03-29T04:00:00.000+02:00"), rounding, 60, tz);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              // 25 Oct 2015 - Daylight Saving Time Ended
 | 
	
		
			
				|  |  |              // at 03:00:00 clocks were turned backward 1 hour to 02:00:00
 | 
	
		
			
				|  |  | -            assertInterval(time("2015-10-25T01:00:00.000+02:00"), time("2015-10-25T02:00:00.000+02:00"), rounding, 60);
 | 
	
		
			
				|  |  | -            assertInterval(time("2015-10-25T02:00:00.000+02:00"), time("2015-10-25T02:00:00.000+01:00"), rounding, 60);
 | 
	
		
			
				|  |  | -            assertInterval(time("2015-10-25T02:00:00.000+01:00"), time("2015-10-25T03:00:00.000+01:00"), rounding, 60);
 | 
	
		
			
				|  |  | +            assertInterval(time("2015-10-25T01:00:00.000+02:00"), time("2015-10-25T02:00:00.000+02:00"), rounding, 60, tz);
 | 
	
		
			
				|  |  | +            assertInterval(time("2015-10-25T02:00:00.000+02:00"), time("2015-10-25T02:00:00.000+01:00"), rounding, 60, tz);
 | 
	
		
			
				|  |  | +            assertInterval(time("2015-10-25T02:00:00.000+01:00"), time("2015-10-25T03:00:00.000+01:00"), rounding, 60, tz);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          {
 | 
	
	
		
			
				|  | @@ -441,12 +435,12 @@ public class TimeZoneRoundingTests extends ESTestCase {
 | 
	
		
			
				|  |  |              // the interval between is 105 minutes long because the hour after transition starts at 00:15
 | 
	
		
			
				|  |  |              // which is not a round value for hourly rounding
 | 
	
		
			
				|  |  |              DateTimeUnit timeUnit = DateTimeUnit.HOUR_OF_DAY;
 | 
	
		
			
				|  |  | -            DateTimeZone timezone = DateTimeZone.forID("Asia/Kathmandu");
 | 
	
		
			
				|  |  | -            TimeZoneRounding rounding = new TimeZoneRounding.TimeUnitRounding(timeUnit, timezone);
 | 
	
		
			
				|  |  | +            DateTimeZone tz = DateTimeZone.forID("Asia/Kathmandu");
 | 
	
		
			
				|  |  | +            TimeZoneRounding rounding = new TimeZoneRounding.TimeUnitRounding(timeUnit, tz);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            assertInterval(time("1985-12-31T22:00:00.000+05:30"), time("1985-12-31T23:00:00.000+05:30"), rounding, 60);
 | 
	
		
			
				|  |  | -            assertInterval(time("1985-12-31T23:00:00.000+05:30"), time("1986-01-01T01:00:00.000+05:45"), rounding, 105);
 | 
	
		
			
				|  |  | -            assertInterval(time("1986-01-01T01:00:00.000+05:45"), time("1986-01-01T02:00:00.000+05:45"), rounding, 60);
 | 
	
		
			
				|  |  | +            assertInterval(time("1985-12-31T22:00:00.000+05:30"), time("1985-12-31T23:00:00.000+05:30"), rounding, 60, tz);
 | 
	
		
			
				|  |  | +            assertInterval(time("1985-12-31T23:00:00.000+05:30"), time("1986-01-01T01:00:00.000+05:45"), rounding, 105, tz);
 | 
	
		
			
				|  |  | +            assertInterval(time("1986-01-01T01:00:00.000+05:45"), time("1986-01-01T02:00:00.000+05:45"), rounding, 60, tz);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          {
 | 
	
	
		
			
				|  | @@ -454,19 +448,19 @@ public class TimeZoneRoundingTests extends ESTestCase {
 | 
	
		
			
				|  |  |              // 3 Mar 1991 - Daylight Saving Time Ended
 | 
	
		
			
				|  |  |              // at 02:00:00 clocks were turned backward 0:30 hours to Sunday, 3 March 1991, 01:30:00
 | 
	
		
			
				|  |  |              DateTimeUnit timeUnit = DateTimeUnit.HOUR_OF_DAY;
 | 
	
		
			
				|  |  | -            DateTimeZone timezone = DateTimeZone.forID("Australia/Lord_Howe");
 | 
	
		
			
				|  |  | -            TimeZoneRounding rounding = new TimeZoneRounding.TimeUnitRounding(timeUnit, timezone);
 | 
	
		
			
				|  |  | +            DateTimeZone tz = DateTimeZone.forID("Australia/Lord_Howe");
 | 
	
		
			
				|  |  | +            TimeZoneRounding rounding = new TimeZoneRounding.TimeUnitRounding(timeUnit, tz);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            assertInterval(time("1991-03-03T00:00:00.000+11:00"), time("1991-03-03T01:00:00.000+11:00"), rounding, 60);
 | 
	
		
			
				|  |  | -            assertInterval(time("1991-03-03T01:00:00.000+11:00"), time("1991-03-03T02:00:00.000+10:30"), rounding, 90);
 | 
	
		
			
				|  |  | -            assertInterval(time("1991-03-03T02:00:00.000+10:30"), time("1991-03-03T03:00:00.000+10:30"), rounding, 60);
 | 
	
		
			
				|  |  | +            assertInterval(time("1991-03-03T00:00:00.000+11:00"), time("1991-03-03T01:00:00.000+11:00"), rounding, 60, tz);
 | 
	
		
			
				|  |  | +            assertInterval(time("1991-03-03T01:00:00.000+11:00"), time("1991-03-03T02:00:00.000+10:30"), rounding, 90, tz);
 | 
	
		
			
				|  |  | +            assertInterval(time("1991-03-03T02:00:00.000+10:30"), time("1991-03-03T03:00:00.000+10:30"), rounding, 60, tz);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              // 27 Oct 1991 - Daylight Saving Time Started
 | 
	
		
			
				|  |  |              // at 02:00:00 clocks were turned forward 0:30 hours to 02:30:00
 | 
	
		
			
				|  |  | -            assertInterval(time("1991-10-27T00:00:00.000+10:30"), time("1991-10-27T01:00:00.000+10:30"), rounding, 60);
 | 
	
		
			
				|  |  | +            assertInterval(time("1991-10-27T00:00:00.000+10:30"), time("1991-10-27T01:00:00.000+10:30"), rounding, 60, tz);
 | 
	
		
			
				|  |  |              // the interval containing the switch time is 90 minutes long
 | 
	
		
			
				|  |  | -            assertInterval(time("1991-10-27T01:00:00.000+10:30"), time("1991-10-27T03:00:00.000+11:00"), rounding, 90);
 | 
	
		
			
				|  |  | -            assertInterval(time("1991-10-27T03:00:00.000+11:00"), time("1991-10-27T04:00:00.000+11:00"), rounding, 60);
 | 
	
		
			
				|  |  | +            assertInterval(time("1991-10-27T01:00:00.000+10:30"), time("1991-10-27T03:00:00.000+11:00"), rounding, 90, tz);
 | 
	
		
			
				|  |  | +            assertInterval(time("1991-10-27T03:00:00.000+11:00"), time("1991-10-27T04:00:00.000+11:00"), rounding, 60, tz);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          {
 | 
	
	
		
			
				|  | @@ -474,24 +468,25 @@ public class TimeZoneRoundingTests extends ESTestCase {
 | 
	
		
			
				|  |  |              // 5 Apr 2015 - Daylight Saving Time Ended
 | 
	
		
			
				|  |  |              // at 03:45:00 clocks were turned backward 1 hour to 02:45:00
 | 
	
		
			
				|  |  |              DateTimeUnit timeUnit = DateTimeUnit.HOUR_OF_DAY;
 | 
	
		
			
				|  |  | -            DateTimeZone timezone = DateTimeZone.forID("Pacific/Chatham");
 | 
	
		
			
				|  |  | -            TimeZoneRounding rounding = new TimeZoneRounding.TimeUnitRounding(timeUnit, timezone);
 | 
	
		
			
				|  |  | +            DateTimeZone tz = DateTimeZone.forID("Pacific/Chatham");
 | 
	
		
			
				|  |  | +            TimeZoneRounding rounding = new TimeZoneRounding.TimeUnitRounding(timeUnit, tz);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            assertInterval(time("2015-04-05T02:00:00.000+13:45"), time("2015-04-05T03:00:00.000+13:45"), rounding, 60);
 | 
	
		
			
				|  |  | -            assertInterval(time("2015-04-05T03:00:00.000+13:45"), time("2015-04-05T03:00:00.000+12:45"), rounding, 60);
 | 
	
		
			
				|  |  | -            assertInterval(time("2015-04-05T03:00:00.000+12:45"), time("2015-04-05T04:00:00.000+12:45"), rounding, 60);
 | 
	
		
			
				|  |  | +            assertInterval(time("2015-04-05T02:00:00.000+13:45"), time("2015-04-05T03:00:00.000+13:45"), rounding, 60, tz);
 | 
	
		
			
				|  |  | +            assertInterval(time("2015-04-05T03:00:00.000+13:45"), time("2015-04-05T03:00:00.000+12:45"), rounding, 60, tz);
 | 
	
		
			
				|  |  | +            assertInterval(time("2015-04-05T03:00:00.000+12:45"), time("2015-04-05T04:00:00.000+12:45"), rounding, 60, tz);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              // 27 Sep 2015 - Daylight Saving Time Started
 | 
	
		
			
				|  |  |              // at 02:45:00 clocks were turned forward 1 hour to 03:45:00
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            assertInterval(time("2015-09-27T01:00:00.000+12:45"), time("2015-09-27T02:00:00.000+12:45"), rounding, 60);
 | 
	
		
			
				|  |  | -            assertInterval(time("2015-09-27T02:00:00.000+12:45"), time("2015-09-27T04:00:00.000+13:45"), rounding, 60);
 | 
	
		
			
				|  |  | -            assertInterval(time("2015-09-27T04:00:00.000+13:45"), time("2015-09-27T05:00:00.000+13:45"), rounding, 60);
 | 
	
		
			
				|  |  | +            assertInterval(time("2015-09-27T01:00:00.000+12:45"), time("2015-09-27T02:00:00.000+12:45"), rounding, 60, tz);
 | 
	
		
			
				|  |  | +            assertInterval(time("2015-09-27T02:00:00.000+12:45"), time("2015-09-27T04:00:00.000+13:45"), rounding, 60, tz);
 | 
	
		
			
				|  |  | +            assertInterval(time("2015-09-27T04:00:00.000+13:45"), time("2015-09-27T05:00:00.000+13:45"), rounding, 60, tz);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    private static void assertInterval(long rounded, long nextRoundingValue, TimeZoneRounding rounding, int minutes) {
 | 
	
		
			
				|  |  | -        assertInterval(rounded, dateBetween(rounded, nextRoundingValue), nextRoundingValue, rounding);
 | 
	
		
			
				|  |  | +    private static void assertInterval(long rounded, long nextRoundingValue, TimeZoneRounding rounding, int minutes,
 | 
	
		
			
				|  |  | +            DateTimeZone tz) {
 | 
	
		
			
				|  |  | +        assertInterval(rounded, dateBetween(rounded, nextRoundingValue), nextRoundingValue, rounding, tz);
 | 
	
		
			
				|  |  |          assertEquals(DateTimeConstants.MILLIS_PER_MINUTE * minutes, nextRoundingValue - rounded);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -502,20 +497,21 @@ public class TimeZoneRoundingTests extends ESTestCase {
 | 
	
		
			
				|  |  |       * @param nextRoundingValue the expected upper end of the rounding interval
 | 
	
		
			
				|  |  |       * @param rounding the rounding instance
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  | -    private static void assertInterval(long rounded, long unrounded, long nextRoundingValue, TimeZoneRounding rounding) {
 | 
	
		
			
				|  |  | +    private static void assertInterval(long rounded, long unrounded, long nextRoundingValue, TimeZoneRounding rounding,
 | 
	
		
			
				|  |  | +            DateTimeZone tz) {
 | 
	
		
			
				|  |  |          assert rounded <= unrounded && unrounded <= nextRoundingValue;
 | 
	
		
			
				|  |  | -        assertThat("rounding should be idempotent " + rounding, rounded, equalTo(rounding.round(rounded)));
 | 
	
		
			
				|  |  | +        assertThat("rounding should be idempotent ", rounding.round(rounded), isDate(rounded, tz));
 | 
	
		
			
				|  |  |          assertThat("rounded value smaller or equal than unrounded" + rounding, rounded, lessThanOrEqualTo(unrounded));
 | 
	
		
			
				|  |  |          assertThat("values less than rounded should round further down" + rounding, rounding.round(rounded - 1), lessThan(rounded));
 | 
	
		
			
				|  |  |          assertThat("nextRounding value should be greater than date" + rounding, nextRoundingValue, greaterThan(unrounded));
 | 
	
		
			
				|  |  | -        assertThat("nextRounding value should be a rounded date" + rounding, nextRoundingValue, equalTo(rounding.round(nextRoundingValue)));
 | 
	
		
			
				|  |  | -        assertThat("values above nextRounding should round down there" + rounding, rounding.round(nextRoundingValue + 1),
 | 
	
		
			
				|  |  | -                equalTo(nextRoundingValue));
 | 
	
		
			
				|  |  | +        assertThat("nextRounding value should be a rounded date", rounding.round(nextRoundingValue), isDate(nextRoundingValue, tz));
 | 
	
		
			
				|  |  | +        assertThat("values above nextRounding should round down there", rounding.round(nextRoundingValue + 1),
 | 
	
		
			
				|  |  | +                isDate(nextRoundingValue, tz));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          long dateBetween = dateBetween(rounded, nextRoundingValue);
 | 
	
		
			
				|  |  | -        assertThat("dateBetween should round down to roundedDate" + rounding, rounding.round(dateBetween), equalTo(rounded));
 | 
	
		
			
				|  |  | -        assertThat("dateBetween should round up to nextRoundingValue" + rounding, rounding.nextRoundingValue(dateBetween),
 | 
	
		
			
				|  |  | -                equalTo(nextRoundingValue));
 | 
	
		
			
				|  |  | +        assertThat("dateBetween should round down to roundedDate", rounding.round(dateBetween), isDate(rounded, tz));
 | 
	
		
			
				|  |  | +        assertThat("dateBetween should round up to nextRoundingValue", rounding.nextRoundingValue(dateBetween),
 | 
	
		
			
				|  |  | +                isDate(nextRoundingValue, tz));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      private static long dateBetween(long lower, long upper) {
 | 
	
	
		
			
				|  | @@ -529,19 +525,30 @@ public class TimeZoneRoundingTests extends ESTestCase {
 | 
	
		
			
				|  |  |          return DateTimeUnit.resolve(id);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    private static String toUTCDateString(long time) {
 | 
	
		
			
				|  |  | -        return new DateTime(time, DateTimeZone.UTC).toString();
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    private static long utc(String time) {
 | 
	
		
			
				|  |  | -        return time(time, DateTimeZone.UTC);
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |      private static long time(String time) {
 | 
	
		
			
				|  |  | -        return ISODateTimeFormat.dateOptionalTimeParser().parseMillis(time);
 | 
	
		
			
				|  |  | +        return time(time, DateTimeZone.UTC);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      private static long time(String time, DateTimeZone zone) {
 | 
	
		
			
				|  |  |          return ISODateTimeFormat.dateOptionalTimeParser().withZone(zone).parseMillis(time);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    private static Matcher<Long> isDate(final long expected, DateTimeZone tz) {
 | 
	
		
			
				|  |  | +        return new TypeSafeMatcher<Long>() {
 | 
	
		
			
				|  |  | +            @Override
 | 
	
		
			
				|  |  | +            public boolean matchesSafely(final Long item) {
 | 
	
		
			
				|  |  | +                return expected == item.longValue();
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            @Override
 | 
	
		
			
				|  |  | +            public void describeTo(Description description) {
 | 
	
		
			
				|  |  | +                description.appendText("Expected: " + new DateTime(expected, tz) + " [" + expected + "] ");
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            @Override
 | 
	
		
			
				|  |  | +            protected void describeMismatchSafely(final Long actual, final Description mismatchDescription) {
 | 
	
		
			
				|  |  | +                mismatchDescription.appendText(" was ").appendValue(new DateTime(actual, tz) + " [" + actual + "]");
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |  }
 |