DateTimeOffset. But I won't spend too much time on what they are not, lets just talk about what they are.
- Two different computers could be given the same integer date value, and they will output different strings.
- If you just capture a date value from the user, for example you might use a date-picker control that returns you a
Dateobject, that object will inherently pick up the user's time zone.
- If there is any ambiguity in that value, how it is resolved is left up to the host environment (usually a browser). Implementations can vary.
- If the user is running Internet Explorer or Safari, they get a value corresponding to 05:00 UTC.
- But if they're running Chrome, Firefox, Opera, or if the code is running in a Node.js application, they get a value corresponding to 06:00 UTC.
This alone wouldn't be so bad, but there's an even bigger problem. The rules in which a conversion of a local date to a UTC date are WRONG. Well, they are if you are working with anything other than dates from right now.
220.127.116.11 Daylight Saving Time Adjustment
The implementation of ECMAScript should not try to determine whether the exact time was subject to daylight saving time, but just whether daylight saving time would have been in effect if the current daylight saving time algorithm had been used at the time. This avoids complications such as taking into account the years that the locale observed daylight saving time year round.
If the host environment provides functionality for determining daylight saving time, the implementation of ECMAScript is free to map the year in question to an equivalent year (same leap-year-ness and same starting week day for the year) for which the host environment provides daylight saving time information. The only restriction is that all equivalent years should produce the same result.
Read that a few times, carefully. Basically it is saying "Whatever the rules are now, you must assume that these rules have always been in effect". What? Really? YES - someone thought this would be ok. That someone, would not be me!
Pass a date like November 7, 2004 (at mignight). At this date in history, daylight savings time was over - by a week (it ended on Oct 31 that year). But ask today, and it will tell you that it is still in daylight time! It's not until a few hours later that it think the transition has happened and applies the standard time offset. To illustrate, this is what happens in Google Chrome:
> new Date(2004,10,7,0,0) Sun Nov 07 2004 00:00:00 GMT-0400 (Eastern Daylight Time) > new Date(2004,10,7,1,0) Sun Nov 07 2004 01:00:00 GMT-0500 (Eastern Standard Time)
The problem is not just limited to web browsers either. If you write server applications using Node.js - you also have this problem.
To be fair, not everyone has this problem. It seems someone at Microsoft had the good sense (or the accidental fortune) of not following the spec. If you are running Internet Explorer - you are fine. It ignores this part of the ECMAScript spec and properly determines the correct timezone offset, using the Windows time zone data stored in the system registry. Good for you, IE. Sometimes breaking with the spec has an upside.
On the other hand, if you are running Firefox, not only do they calculate the zone wrong, but they also mess up the names! They can't seem to get "daylight" and "standard" straight - they have them inverted. You can read about this here. This is a bug, and I'm sure they will fix it in an upcoming version.
So what to do about the bad spec? Well it seems someone out there has already realized this flaw and corrected it for the upcoming ECMAScript 6. The current draft is here, and states:
An implementation of ECMAScript is expected to make its best effort to determine the local daylight saving time adjustment. An implementation dependent algorithm using best available information on time zones to determine the local daylight saving time adjustment DaylightSavingTA(t), measured in milliseconds.
This is much better. But who knows how long it will be before this gets ratified and makes its way into the browsers? And what about all of the current and old browsers out there?
I would like to thank Jeff Walden, and "bpa" for helping to uncover this issue recently. You can read more here.
I would also like to give a big smack upside the head to the folks at ECMA that let this slide. A spec should never be written as "don't follow the normal rules, follow our rules instead because we think they are easier". Did they not stop to consider that the host environment would probably already have the capability to do this right? It should have been a very simple matter to say that timezone decisions should be left to the host environment.
Apparently Internet Explorer is indeed affected by this issue, at least through version 9. IE10 appears to be following the ECMAScript6 recommendation. Not sure if it was by accident or by design, but it's a good thing.
The latest draft of ES6 has an additional note:
NOTE It is recommended that implementations use the time zone information of the IANA Time Zone Database.
This is excellent. Yay!
The issue mentioned with regards to FireFox flipping the names for standard and daylight time appears to be resolved in FireFox 25. The other issues still remain.
Apparently it was not fixed in FireFox 25. I still see the issue in FireFox 30, and even uninstalling and re-installing FireFox 25 does not fix the problem. Hmmmm...
This is also been fixed in the ECMA Internationalization API (ECMA-402). In version 1.0:
12.3.2 Intl.DateTimeFormat.prototype.format ... The calculations should use best available information about the specified calendar and time zone. If the calendar is "gregory", then the calculations must match the algorithms specified in ES5, 15.9.1, except that calculations are not bound by the restrictions on the use of best available information on time zones for local time zone adjustment and daylight saving time adjustment imposed by ES5, 18.104.22.168 and 22.214.171.124.
A similar wording also appears in version 2.0 of the spec, in section 12.3.4.