Reputation: 93
Riddle me this: why does this simple JUnit assertion fail?
public void testParseDate() throws ParseException {
final SimpleDateFormat formatter = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss z");
formatter.setTimeZone(UTC);
final Calendar c = new GregorianCalendar();
c.setTime(formatter.parse("2013-03-02 11:59:59 UTC"));
assertEquals(11, c.get(HOUR_OF_DAY));
}
I would have expected the hour of day to be 11, but according to JUnit, the hour of day is 12.
junit.framework.AssertionFailedError: expected:<11> but was:<12>
at junit.framework.Assert.fail(Assert.java:47)
... snip ...
Upvotes: 9
Views: 8287
Reputation: 7288
The default constructor of the Gregorian Calendar uses the local timezone of the machine. If that's different from UTC, you get this behavior. Try to use the GregorianCalendar(TimeZone) constructor and pass UTC into that.
This will work:
public void testParseDate() throws Exception {
TimeZone UTC = TimeZone.getTimeZone("UTC");
// Create a UTC formatter
final SimpleDateFormat formatter = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss z");
formatter.setTimeZone(UTC);
// Create a UTC Gregorian Calendar (stores internally in UTC, so
// get(Calendar.HOUR_OF_DAY) returns in UTC instead of in the
// local machine's timezone.
final Calendar c = new GregorianCalendar(UTC);
// Ask the formatter for a date representation and pass that
// into the GregorianCalendar (which will convert it into
// it's internal timezone, which is also UTC.
c.setTime(formatter.parse("2013-03-02 11:59:59 UTC"));
// Output the UTC hour of day
assertEquals(11, c.get(Calendar.HOUR_OF_DAY));
}
Upvotes: 8
Reputation: 5638
You also need to set up the timezone/daylight savings time for the calendar. Have a look at this snippet taken from the documentation:
// create a Pacific Standard Time time zone
SimpleTimeZone pdt = new SimpleTimeZone(-8 * 60 * 60 * 1000, ids[0]);
// set up rules for daylight savings time
pdt.setStartRule(Calendar.APRIL, 1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
pdt.setEndRule(Calendar.OCTOBER, -1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
// create a GregorianCalendar with the Pacific Daylight time zone
// and the current date and time
Calendar calendar = new GregorianCalendar(pdt);
Upvotes: 1