JavaScript and ISO 8601
If you've ever worked with JavaScript against services like Twitter or YouTube. You've most likely come across date/times based on the ISO 8601 standard"
ISO 8601 is a standard that defines how dates/times should be formatted (YYYY-MM-DDThh:mm:ss.sTZD). Unfortunately, it doesn't play nice with many browser JavaScript implementations.
To complicate things further, It comes in different tasty flavors, behold:
Twitter API ⇒ Wed Apr 07 17:04:01 +0000 2010 YouTube API ⇒ 2010-06-05T22:07:03.000Z
Normally, when creating a new date object you pass the date string into the constructor.
var birthday = new Date("2010-06-05T22:07:03.000Z");
The above works fine in Firefox (to my knowledge 3.5 and above). However, Webkit (Safari and Chrome) and Internet Explorer (all versions) will throw an Invalid Date exception. This was somewhat confusing for me since I usually do all my development in Firefox and it took a while to figure out what was going on.
After scratching my head for a while, and spending some time looking into the issue I found two very valuable resources.
Parsing ISO 8601 with JavaScript
Paul Sowden has posted some useful code over at his blog. Thanks Paul.
Date.prototype.setISO8601 = function (string) {
var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
"(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?" +
"(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";
var d = string.match(new RegExp(regexp));
var offset = 0;
var date = new Date(d[1], 0, 1);
if (d[3]) { date.setMonth(d[3] - 1); }
if (d[5]) { date.setDate(d[5]); }
if (d[7]) { date.setHours(d[7]); }
if (d[8]) { date.setMinutes(d[8]); }
if (d[10]) { date.setSeconds(d[10]); }
if (d[12]) { date.setMilliseconds(Number("0." + d[12]) * 1000); }
if (d[14]) {
offset = (Number(d[16]) * 60) + Number(d[17]);
offset *= ((d[15] == '-') ? 1 : -1);
}
offset -= date.getTimezoneOffset();
time = (Number(date) + (offset * 60 * 1000));
this.setTime(Number(time));
}
By adding a method to the Date objects prototype we can now do the following:
var today = new Date();
today.setISO8601('2010-06-05T22:07:03.000Z');
Great Success! Though, beware that this code is somewhat performance heavy, and usually when working with API's it involves parsing a s*** load of data. Therefor, If you can, I suggest you do the parsing server-side.
Making ISO 8601 dates with JavaScript
The following snippet is taken from the Mozilla Developer Center and is useful if you want to convert dates into the IS0 8601 format:
function ISODateString(d) {
function pad(n){
return n<10 ? '0'+n : n
}
return d.getUTCFullYear()+'-'
+ pad(d.getUTCMonth()+1)+'-'
+ pad(d.getUTCDate())+'T'
+ pad(d.getUTCHours())+':'
+ pad(d.getUTCMinutes())+':'
+ pad(d.getUTCSeconds())+'Z'
}
var d = new Date();
print(ISODateString(d));
And that is all. Rejoice!