[philiptellis] /bb|[^b]{2}/
Never stop Grokking

Thursday, September 18, 2008

Date inconsistencies in Javascript

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();
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


September 19, 2008 11:33 PM

In Windows XP :

FF 3.0.1 : Sat Sep 20 2008 08:56:00 GMT +0530 (India Standard Time) and IST

Opera 9.52 : Sat Sep 20 2008 08:56:45 GMT+0530 and SS20200808:58:01GMT+0530

IE 6.0 : Sat Sep 20 08:59:43 UTC +0530 2008 and SS2009:00:15UTC+05302008

Google Chrome : Sat Sep 20 2008 09:01:30 GMT +0530 (India Standard Time)and IST

Safari 3.1.2 : Sat Sep 20 2008 09:02:52 GMT +0530 (India Standard Time) and IST

Post a Comment