I have some code that uses Calendar.set() to return the beginning of the hour for a given date value. I encountered the following issue on Sunday Nov 4th, 2012 (Eastern Timezone – EDT to EST switchover):
public void testStartOfHourDST1() {
Calendar cal = Calendar.getInstance();
long time = 1352005200000L; // Nov 4, 2012, 1AM EDT
cal.setTimeInMillis(time);
cal.set(Calendar.MILLISECOND, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MINUTE, 0);
System.out.println(new Date(time));
System.out.println(new Date(cal.getTimeInMillis()));
System.out.println(System.getProperty("java.version"));
assertEquals(cal.getTimeInMillis(), time); // fails
return;
}
Ouput:
Sun Nov 04 01:00:00 EDT 2012
Sun Nov 04 01:00:00 EST 2012
1.6.0_35
Perhaps this is not the correct way to be using calendar, but running the same test for the next hour (or previous hour) works fine. Is this a JVM issue?
Thanks
It’s not really an issue, in the sense that it is deterministic and doing what it was programmed to do. It’s an issue if you would prefer that it pick the earlier of the two 1ams!
After changing fields on the Calendar the only information it has is “1am in US/Eastern”. Well, your timezone had two 1ams that day, which one is it supposed to pick? The authors of OpenJDK made a decision that when presented with this ambiguity, they would always interpret it as the later one, in standard time. This comment is from java.util.GregorianCalendar OpenJDK 6:
If you print out the actual values of the numbers you will see
cal.getTimeInMillis()has actually been changed by an hour from the value oftime.