Assuming Brasilia GMT -0300: DST on 21/10/2012 at 00:00:00, when the clock should be advanced by one hour
Java
new Date(2012 - 1900, 9, 21, 0, 0, 0)
Sun Oct 21 01:00:00 BRST 2012
Chrome/FireFox (console)
new Date(2012, 9, 21, 0, 0 ,0)
Sat Oct 20 2012 23:00:00 GMT-0300 (Hora oficial do Brasil)
The result in Java is what I was expecting, but the result in JS I can not understand. I found this post where bjornd says
This is an absolutely correct behavior
but didn't explain why this behavior is OK.
My question is:
Why JS is returning a date one hour in the past?
P.S. I know Date is marked for "deprecation", but I'm using GWT; Date is my only option.
Basically, that answer was incorrect as far as I can see. I'm not entirely happy with the Java version, even.
Fundamentally, you're trying to construct a local date/time which never happened. Translating from local time to UTC is always tricky, as there are three possibilities:
- Unambiguous mapping, which in most time zones is the case for all but two hours per year
- Ambiguous mapping, during a backward transition, where the same local time period occurs twice (e.g. local time goes 12:59am, 1am, ... 1:59am, 1am, 1:59am, 2am)
- "Gap" mapping, where a local time period simply doesn't exist (e.g. local time goes 12:59am, 2am, 2:01am)
Brazil moves its clocks forward at midnight, so local time actually goes:
October 20th 11:58pm
October 20th 11:59pm
October 21st 01:00am
October 21st 01:01am
The local time you've asked for simply never happened. It looks like Java is just assuming you want to roll it forward... whereas JavaScript is getting confused :( The JavaScript result would be more understandable (but still incorrect) if you were asking for midnight at the start of February 16th 2013, for example - where the clocks would have gone back to 11pm on the 15th. 12am on the 16th is unambiguous, as it can only happen after the "second" 11pm-11:59pm on the 15th.
A good date/time API (in my very biased view) would force you to say how you want to happen ambiguity and gaps when you do the conversion.