I am trying to understand why is it that the result of the code is -2, initially I thought it should be -1, but this one really puzzled me
LocalDateTime ld1 = LocalDateTime.of(2015, Month.NOVEMBER, 1, 2, 0);
ZonedDateTime zd1 = ZonedDateTime.of(ld1, ZoneId.of("US/Eastern"));
LocalDateTime ld2 = LocalDateTime.of(2015, Month.NOVEMBER, 1, 1, 0);
ZonedDateTime zd2 = ZonedDateTime.of(ld2, ZoneId.of("US/Eastern"));
long x = ChronoUnit.HOURS.between(zd1, zd2);
System.out.println(x);
output : -2
LocalDateTime ld1 = LocalDateTime.of(2015, Month.NOVEMBER, 1, 3, 0);
ZonedDateTime zd1 = ZonedDateTime.of(ld1, ZoneId.of("US/Eastern"));
LocalDateTime ld2 = LocalDateTime.of(2015, Month.NOVEMBER, 1, 2, 0);
ZonedDateTime zd2 = ZonedDateTime.of(ld2, ZoneId.of("US/Eastern"));
long x = ChronoUnit.HOURS.between(zd1, zd2);
System.out.println(x);
Below are the examples which results works as I expected!
output : -1
LocalDateTime ld1 = LocalDateTime.of(2015, Month.NOVEMBER, 1, 2, 0);
ZonedDateTime zd1 = ZonedDateTime.of(ld1, ZoneId.of("US/Eastern"));
LocalDateTime ld2 = LocalDateTime.of(2015, Month.NOVEMBER, 1, 3, 0);
ZonedDateTime zd2 = ZonedDateTime.of(ld2, ZoneId.of("US/Eastern"));
long x = ChronoUnit.HOURS.between(zd1, zd2);
System.out.println(x);
output : 1
If someone can help me understand this better, really appreciated.
US/Eastern
, in IANA database (the source where those names come from) is the same as America/New_York
timezone (check this list to check the equivalence - search for US/Eastern
).
And in America/New_York
timezone, Daylight Saving Time ended at November 1st 2015: at 2 AM, clocks shift back 1 hour to 1 AM, and offset changed from -04:00
to -05:00
.
If you check the ZonedDateTime
's, you'll see the offset change:
System.out.println(zd1);
System.out.println(zd2);
The output is:
2015-11-01T02:00-05:00[US/Eastern]
2015-11-01T01:00-04:00[US/Eastern]
If you see the corresponding Instant
, you'll see both dates in UTC:
System.out.println(zd1.toInstant());
System.out.println(zd2.toInstant());
2015-11-01T07:00:00Z
2015-11-01T05:00:00Z
Note that the difference between those dates is 2 hours. You can check this by adding 1 and 2 hours to zd2
:
System.out.println(zd2);
System.out.println(zd2.plusHours(1));
System.out.println(zd2.plusHours(2));
The output is:
2015-11-01T01:00-04:00[US/Eastern]
2015-11-01T01:00-05:00[US/Eastern]
2015-11-01T02:00-05:00[US/Eastern]
So, starting at 1 AM in offset -04:00
, 1 hour later you are at 2 AM in offset -04:00
, but due to DST change, clocks shift back to 1 AM in offset -05:00
. Then, 1 hour later, you're at 2 AM in offset 05:00
(zd1
). That's why the difference is 2 hours.
This doesn't happen in your second test, because both dates are in the same offset (-05:00
), after DST change occurred. So, the difference is just 1 hour. You can again check this by printing the dates and the corresponding Instant
:
LocalDateTime ld1 = LocalDateTime.of(2015, Month.NOVEMBER, 1, 2, 0);
ZonedDateTime zd1 = ZonedDateTime.of(ld1, ZoneId.of("US/Eastern"));
LocalDateTime ld2 = LocalDateTime.of(2015, Month.NOVEMBER, 1, 3, 0);
ZonedDateTime zd2 = ZonedDateTime.of(ld2, ZoneId.of("US/Eastern"));
System.out.println(zd1);
System.out.println(zd2);
System.out.println(zd1.toInstant());
System.out.println(zd2.toInstant());
2015-11-01T02:00-05:00[US/Eastern]
2015-11-01T03:00-05:00[US/Eastern]
2015-11-01T07:00:00Z
2015-11-01T08:00:00Z
Note that the offset is the same, and by the corresponding UTC Instant
we can see that the difference is only 1 hour.