This week I had the particular displeasure of working with Date parsing algorithms across browsers. The internet, in general, has pretty much settled on ISO 8601 and variations thereof as the standard formats for representing date / time information. For example, the W3C specifies a subset of 8601 as the official date/time format in the HTML5 specification and for the datetime attribute of the time element.
The rub, of course, comes in when you decide that you want to parse dates formatted like so. On Chrome, Safari, Firefox, and IE 9+, it’s actually not that bad. You can correctly use the new Date constructor and get something like…
> new Date(“2014-02-07T07:06:41Z”) Fri Feb 07 2014 02:06:41 GMT-0500 (EST)
Seems legit right? Unfortunately, I live in a world that requires me to also support IE8, which does not support 8601 properly.
> new Date(“2014-02-07T07:06:41Z”) NaN
Boom! Well it’s right, in a way. A date is technically not a number.
Running parallel to this I was also making use of Date.js, which in an ideal world would smooth over these discrepancies for us. Date.js, however, actually breaks 8601 support in its implementation of Date.parse. So, bupkis on that front. I needed to evaluate options to get date parsing working reliably cross-browser.
The first option I evaluated was using a different format for dates that were sent down from the server. It turns out that all browsers can properly interpret a date formatted like so:
Fri Feb 07 2014 02:06:41 GMT-0500 (EST)
So, if we could just send down that format then, in theory, things “just start working.” Unfortunately I found a few issues with this plan when I started implementing it.
My conclusion on realizing these points was that switching date formats was the incorrect approach. Standards compliance aside, to get this solution working properly, we were going to essentially need to modify every library that had correctly standardized on ISO 8601 to use the format we wanted. It was the date parsing equivalent of 1984.
The option I decided to pursue in the end was to double down on ISO 8601. This meant I needed to do a few things. First, I needed to fix the fact that Date.parse was broken because of Date.js. Second, I needed to somehow augment that Date.parse method such that IE8 could parse ISO 8601 dates. This was not a completely new rodeo. I ran across some helpful solutions on StackOverflow that pointed me in the right direction. The first was an alternate implementation of Date.js’s parse method and the second was a pretty succinct implementation of a manual 8601 parser.
I mish-mashed these implementations together into my own implementation that essentially amounts to the following logic:
Ultimately, this appears to be pretty stellar. We now just need to make sure we standardize our code to use Date.parse instead of the Date constructor, and our intelligent Date.parse method will take care of the rest. Browsers that natively support 8601 won’t be negatively impacted by the manual algorithm, and we still have the full power of the Date.js grammar parsing when we want it.
There are, however, a few interesting notes with this implementation.
Ultimately, after beating my head against the brick wall that is IE for several hours I was pretty happy with the way this came out. As always, would love to hear some comment love on the solution. Let me know what you think. ?