Ever since I built my
javascript strftime implementation, I've been playing around with dates and date formatting in javascript. One of the things that users of the library have been happy about is the ease with which dates can be localised using the library, and it's this particular feature that's been frustrating me a lot when dealing with time zones. Let me get this out of my head.
The javascript engine of various browsers stringify dates in subtly different ways, but different enough to mess up time zone parsing.
Here's what I'm talking about. Tell me what your browser says when you click the following two links:
Try this snippet of code in your favourite browsers:
var d = new Date();
alert(d.toString());
alert(d.toLocaleString());
I've seen different results on Firefox, IE, Opera and Safari. Firefox is the worst offender with different results across platforms. The following are my results:
- Firefox 2 & 3 on Linux and Mac OS X, and Safari on Mac OS X
- Thu Sep 18 2008 19:20:23 GMT-0700 (PDT)
- Firefox 2 & 3 on Windows
- Thu Sep 18 2008 19:20:23 GMT-0700 (Pacific Daylight Time)
- Google Chrome
- Thu Sep 18 2008 19:20:23 GMT-0700 (Pacific Daylight Time)
However it displays GST instead of GMT if your timezone is set to GMT
- Opera 9.52 on Linux and Mac OS X
- Thu Sep 18 2008 19:20:23 GMT-0700
- IE 6, 7, 8 on Windows
- Thu Sep 18 19:20:23 PDT 2008
I've only tested this in the PDT time zone, but the results are diverse enough to make parsing out the time zone annoying (except for Opera, where it's impossible). This is what I came up with:
d.toString().replace(/^.*:\d\d( GMT[+-]\d+)? \(?([A-Za-z ]+)\)?\d*$/, '$2').replace(/[a-z ]/g, '');
I derived this regex over a couple of iterations. It started out taking care of the Firefox on Mac & Linux and Safari case:
d.toString().replace(/^.* \(([^)]+)\)$/, '$1');
Next, I added support for Firefox on Windows by getting rid of all lowercase letters and spaces:
d.toString().replace(/^.* \(([A-Za-z ]+)\)$/, '$1').replace(/[a-z ]/g, '');
Finally, I added in support for IE, by checking for a string of characters that fell between seconds and year:
d.toString().replace(/^.*:\d\d( GMT[+-]\d+)? \(?([A-Za-z ]+)\)?\d*$/, '$2').replace(/[a-z ]/g, '');
This is by no means fool proof. It could break with time zones and browsers that I haven't encountered yet, so I'm asking everyone for help in figuring this out.
Short of asking all browser authors to be consistent in their
Date.toString()
implementations, how do I figure out the timezone string for a date? I've even thought about building a table of offsets to timezone strings, but there isn't a one to one mapping for that.
I've also noticed that the timezone is always displayed in English, even when I change my system locale. Perhaps this is different for you. Let me know.
And yo, Google, what's up with Greenwich
Standard Time?
Short URL:
http://tr.im/jsinconsistentdate