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