I'm trying to grok time-handling, and I've stumbled upon something in Java that has me somewhat baffled. Take this sample code:
public static void main(String[] args)
{
//Calendar set to 12:00 AM of the current day (Eastern Daylight Time)
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT-4"));
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
/////
//Calendar set to 12:00 AM of the current day (UTC time)
Calendar utcCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
utcCal.set(Calendar.HOUR_OF_DAY, 0);
utcCal.set(Calendar.MINUTE, 0);
utcCal.set(Calendar.SECOND, 0);
utcCal.set(Calendar.MILLISECOND, 0);
/////
long oneHourMilliseconds = 3600000;
System.out.println((cal.getTimeInMillis() - utcCal.getTimeInMillis()) / oneHourMilliseconds);
}
I visualize the algorithm for calculating the time represented by cal taking 1 of 2 forms:
Epoch - 4 * oneHourMilliseconds).Both of these algorithms should yield a result that is 4 hours behind that of utcCal, however running the code returns 4 .
Can someone explain to me why cal, despite being set to a time zone 4 hours behind that of utcCal, ends up having a millisecond value 4 hours after that of utcCal? Shouldn't the code be returning -4?
It's an unfortunate piece of history. A time zone with an ID of "GMT-4" is what you'd expect to be "UTC+4", i.e. it's 4 hours ahead of UTC.
From the etcetera file from tzdb:
# We use POSIX-style signs in the Zone names and the output abbreviations,
# even though this is the opposite of what many people expect.
# POSIX has positive signs west of Greenwich, but many people expect
# positive signs east of Greenwich. For example, TZ='Etc/GMT+4' uses
# the abbreviation "GMT+4" and corresponds to 4 hours behind UTC
# (i.e. west of Greenwich) even though many people would expect it to
# mean 4 hours ahead of UTC (i.e. east of Greenwich).
And from this similar explanation:
If you can at all manage it, avoid definitions and use of the GMT timezones...
The calendar cal is set to 2012-04-18 00:00:00 of the timezone GMT-4.
That moment corresponds to 2012-04-18 04:00:00 in UTC (in other words, when it's 12 AM in the timezone GMT-4, it's 4 AM in UTC).
The calendar utcCal is set to 2012-04-18 00:00:00 of the timezone UTC.
The difference between 2012-04-18 04:00:00 and 2012-04-18 00:00:00 is 4 hours, so you see 4 being printed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With