4

I have a question regarding Date/Time/Timezones differences in the Browser (JS) and Java running on the same machine in the same timezone. I am aware that systems should agree on the timezone (UTC mainly, use Date.UTC) to avoid such issues. Nevertheless I thought this example should work fine.

For this I created some dates with the Browser (Chrome) and used the same millis to create a Date with Java.

Here is an example which I don't understand. Please help me to understand.

Chrome (JavaScript):

new Date(1980,9,10,0,0,0,0) Fri Oct 10 1980 00:00:00 GMT+0200 (Mitteleuropäische Sommerzeit) The millis are: 339976800000

Java:

new Date(339976800000l) Thu Oct 09 23:00:00 CET 1980

Please note Java applies CET wheras JavaScript applies CEST.

chris1069603
  • 433
  • 5
  • 15
  • 2
    23:00 CET == 00:00 CEST (difference between winter and summer time). – assylias Apr 27 '16 at 20:54
  • Please read the question carefully, I wonder why Java uses CET instead of CEST in this situation. – chris1069603 Apr 27 '16 at 20:55
  • 1
    Please provide the actual code you use in Java. There is no constructor of `java.util.Date` which takes 7 parameters; also, you'd need to subtract offsets for year and month. Also, please show your configured timezone in both environments. – Andy Turner Apr 27 '16 at 20:57
  • Thanks, will edit. Actually I just copied over the millis to Java. – chris1069603 Apr 27 '16 at 20:59
  • 1
    The 9th of October 1980 was in winter time. – assylias Apr 27 '16 at 21:00
  • It is on the same machine, so I thought it will should use the Windows system TZ. – chris1069603 Apr 27 '16 at 21:01
  • @assylias speaks the truth (at least according to http://www.timeanddate.com/time/change/germany/berlin?year=1980) – Andy Turner Apr 27 '16 at 21:02
  • That is perfect, so Chrome gets it wrong? I'm confused. I thought the same millis on the same system talking the same TZ should get the same result. – chris1069603 Apr 27 '16 at 21:04
  • I think I figured it out. Maybe it is documented somewhere but the rules for the change from summer/winter time have changed. Not sure though but Chrome seems to apply the new rules for older dates whereas Java takes into account the weird history of daylight saving. This is actually really interesting and maybe someone can point to some documentation on this. Thanks. – chris1069603 Apr 27 '16 at 21:25
  • Be careful what you wish for @chris1069603 - I know that Java is based on the IANA time zone data - http://www.iana.org/time-zones - but to really learn what's under the covers you'll need to look at the individual timezone files - the most recent being http://www.iana.org/time-zones/repository/releases/tzdata2016d.tar.gz. In there, you would want to look at the "europe" file (or indeed any of them) as they are a fascinating insight into the the amount of work needed to maintain timezone data. – stdunbar Apr 27 '16 at 22:12
  • Thank you for your comment. This is rellay fascinating. I stumbled upon this, which explains the actual root of the problem. http://stackoverflow.com/questions/16946002/javascript-time-zone-is-wrong-for-past-daylight-saving-time-transition-rules – chris1069603 Apr 29 '16 at 18:48

1 Answers1

2

tl;dr

Definition of Daylight Saving Time (DST) changed between 1980 and 2016.

Previously DST ended on last Sunday of September, later changed to end on last Sunday of October.

Detailed Answer

The missing piece of the puzzle is knowing the specific time zone used in your calculations. Your Question and example code fails to tell us exactly what time zones were utilized. My discussion here assumes you used a time zone similar to that of Europe/Berlin (based on your use of text apparently localized in German language), in that its definition of DST changed.

CET and CEST are not actually time zones. Such abbreviations are not standardized, nor even unique. Avoid them.

Instead use proper time zone names as defined in the tz database. A true time zone is an offset-from-UTC plus a set of rules for handling anomalies past, present, and future, such as Daylight Saving Time (DST).

The time zone rules change, and change surprisingly often. Bored politicians, I suppose.

For example, Europe/Berlin changed in 1980 to end DST on last Sunday in September. So DST does not apply to your date of October 1980. Since 1996 EU rules apply, extending DST to last Sunday of October rather than September. Thus DST does apply to your October 10th date in 2016.

The code in the Question uses month “9” which actually means “10”, October. One of the many problems with the old java.util.Date class is that it counts months by zero-based counting, 0 = January. One of many many reasons to avoid the old date-time classes. In contrast, in java.time the month number for October is indeed 10 as you would expect, and you can use a constant from the Month enum to be even more clear.

By the way, another poor design choice in java.util.Date is that when constructing a Date object as you did in the Question, your JVM’s current default time zone was applied, and the result adjusted back to UTC. This further complicates your Question as you did not report the time zone in use at the time you ran your code.

By the way, JavaScript, like nearly every development platform, has poor support for date-time work. Try to use Java and its built-in java.time framework whenever possible. See Oracle Tutorial. You can witness java.time in action in the following example code. We get October 10th in 1980 and in 2016 for Europe/Berlin.

ZoneId zoneId = ZoneId.of ( "Europe/Berlin" );;

ZonedDateTime zdt_1980 = ZonedDateTime.of ( 1980 , Month.OCTOBER.getValue () , 10 , 0 , 0 , 0 , 0 , zoneId );
long seconds_1980 = zdt_1980.toEpochSecond ();

ZonedDateTime zdt_2016 = ZonedDateTime.of ( 2016 , Month.OCTOBER.getValue () , 10 , 0 , 0 , 0 , 0 , zoneId );
long seconds_2016 = zdt_2016.toEpochSecond ();

Dump to console.

System.out.println ( "zoneId: " + zoneId );
System.out.println ( "zdt_1980: " + zdt_1980 + " | seconds_1980: " + seconds_1980 );
System.out.println ( "zdt_2016: " + zdt_2016 + " | seconds_2016: " + seconds_2016 );

You can see in the results that the offset-from-UTC changed from one hour ahead of UTC (+01:00) in the old days to now two hours ahead of UTC (+02:00). The difference is because of the re-definition of DST.

So, this explains why you got "CET" in 1980 but "CEST" in 2016. The S in CEST that you got for 2016 means "Summer", and “Summer Time” means DST. In this year of 2016, most of October is in "Summer Time" (DST). In 1980, October was not in DST/"Summer Time"/"CEST".

zoneId: Europe/Berlin

zdt_1980: 1980-10-10T00:00+01:00[Europe/Berlin] | seconds_1980: 339980400

zdt_2016: 2016-10-10T00:00+02:00[Europe/Berlin] | seconds_2016: 1476050400

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • Thank you very much for all the information. The code above was only used for demonstration purposes. The client & server run in the same timezone. So the actual issue was that JS and Java deal with past dates differently. JS only applies the current DST rules as described here http://stackoverflow.com/questions/16946002/javascript-time-zone-is-wrong-for-past-daylight-saving-time-transition-rules – chris1069603 May 07 '16 at 05:21
  • @chris1069603 Actually your situation cannot really be diagnosed until you determine what time zone is being applied in your JavaScript and in your Java. Please add code in both cases to get and report the time zone. Until then you are just guessing and making assumptions. In Java you can call [`ZoneId.systemDefault()`](https://docs.oracle.com/javase/8/docs/api/java/time/ZoneId.html#systemDefault--) or [`TimeZone.getDefault()`](http://docs.oracle.com/javase/8/docs/api/java/util/TimeZone.html#getDefault--). For JavaScript, I don't know. – Basil Bourque May 07 '16 at 05:46
  • It is indeed Europe/Berlin. The attached link explains the Javascript behavior quite well. I edited the question according to your input a bit to make the question clearer. I feel I failed miserably at first when I read through the comments. Sorry. Hope we can make this useful for others. For me it was a big surprise realizing Java and JS apply different rules – chris1069603 May 07 '16 at 11:29