I'm having a hard time understanding the behavior of the following code:
TimeZone zone = TimeZone.getTimeZone("Asia/Jerusalem");
DateFormat format = DateFormat.getDateTimeInstance();
format.setTimeZone(zone);
//printing out 4 different epoch dates
//print out using formatter with TZ
System.out.println(format.format(new Date(-1712458800000L)));
//print using Date's toString method
System.out.println(new Date(-1712458800000L));
System.out.println(format.format(new Date(-57844760000L)));
System.out.println(new Date(-57844760000L));
System.out.println(format.format(new Date(-1888228760000L)));
System.out.println(new Date(-1888228760000L));
System.out.println(format.format(new Date(1456920000000L)));
System.out.println(new Date(1456920000000L));
When running on my local machine (Timezone GMT+2 Jerusalem) with "Automatically adjust clock for DST" checked in windows (that makes me GMT+3) It produces the following output:
Sep 26, 1915 11:20:40 PM
Sun Sep 26 23:20:40 IST 1915
Mar 2, 1968 2:00:40 PM
Sat Mar 02 14:00:40 IST 1968
Mar 2, 1910 2:21:20 PM
Wed Mar 02 14:21:20 IST 1910
Mar 2, 2016 2:00:00 PM
Wed Mar 02 14:00:00 IST 2016
But when I'm unchecking it (that makes me GMT+2) running the same code produces
Sep 26, 1915 11:20:40 PM
Sun Sep 26 23:00:00 GMT+02:00 1915
Mar 2, 1968 2:00:40 PM
Sat Mar 02 14:00:40 GMT+02:00 1968
Mar 2, 1910 2:21:20 PM
Wed Mar 02 14:00:40 GMT+02:00 1910
Mar 2, 2016 2:00:00 PM
Wed Mar 02 14:00:00 GMT+02:00 2016
The first and third example differ in the minutes and seconds when using toString() of Date. As you can see, when I'm explicitly setting the TZ using DateFormat it prints out the same result. What am I missing here?
Thanks!
Let's just look at your 1915 example. The value -1712458800000 as millis-since-the-unix-epoch is 1915-09-26T21:00:00Z - in other words, exactly 9pm UTC.
Now back in 1915, the UTC offset in Jerusalem was +2:20:40, which is why you see "Sep 26, 1915 11:20:40 PM" in the first line of your output. However, when you turn off DST in Windows, either Windows or Java is treating that as saying "Treat this as a fixed time zone of UTC+2." It's not really "Treat this as Jerusalem without DST changes, but with other changes." So you see a value of UTC+2 in your second line, which is "Sun Sep 26 23:00:00 GMT+02:00 1915".
Basically, the concept of "this time zone without DST" is a very odd one, and has been simplified (again, I'm not sure whether it's by Windows or Java) to just a fixed offset. That's fine when the "standard" offset doesn't change, but it causes issues like this when it does. Most time zones haven't changed their standard offset in reasonably-modern history, but there are quite a few changes back in the early 20th century.
See more on this question at Stackoverflow