Javascript: Convert a Date object to an ISO 8601 formatted string

 
One of my technical New Year’s Resolutions is to clean up my collection of code snippets. Over the years I’ve built up a sizeable collection but many of them are either not very useful anymore or could be improved. After deleting those that are no longer useful I am cleaning up the code of those that are left, making sure they validate in the latest version of JSLint, before posting them to this blog and sharing them on Gist and Snipplr, with a jsFiddle thrown in where useful.

The first snippet posted is a simple shim to convert a Javascript date object to an ISO 8601 formatted string. The format of these strings is comprehensively detailed  on the W3C website but, simply put, it looks like this:


Screenshot_1_13_13_9_18_PM-2

As well as being a simple, easy-to-understand string format it’s well-supported in many languages which makes it useful for data interchange. Most modern languages have a function to take a date and return an ISO 8601 string. In Javascript, this function is ‘ISODateString’ but, unfortunately, it isn’t implemented in all commonly used browsers – significantly, Internet Explorer 8 and earlier don’t include it.

The simple solution is a small function that will use the ‘ISODateString’ when it is available and fallback to a d-i-y solution when it isn’t. In that way we get a working solution now and the performance and reliability improvements of a native browser solution when it is available without the need to change our code.


if (typeof Date.prototype.toISOString !== 'function') {

    (function () {

        'use strict';

        // Function which takes a 1 or 2-digit number and returns
        // it as a two-character string, padded with
        // an extra leading zero, if necessary.
        function pad(number) {
            var r = String(number);
            if (r.length === 1) {
                r = '0' + r;
            }
            return r;
        }

        Date.prototype.toISOString = function () {
            return this.getUTCFullYear()
                + '-' + pad(this.getUTCMonth() + 1)
                + '-' + pad(this.getUTCDate())
                + 'T' + pad(this.getUTCHours())
                + ':' + pad(this.getUTCMinutes())
                + ':' + pad(this.getUTCSeconds())
                + '.' + String((this.getUTCMilliseconds() / 1000).toFixed(3)).slice(2, 5)
                + 'Z';
         };

    }());
}

The structure of the snippet is straightforward. In line 1 I check if the native function exists. If it does then nothing more needs to be done. If it doesn’t then I create a new function with the same name as the native one which takes a date object and concatenates together its constituent parts to make the ISO string. As ISO 8601 requires that Month, Day, Hours, etc. are two digits there is another function – ‘Pad’ – which takes a number and ensures it is two digits long by padding with a leading zero, if necessary. By wrapping the whole thing in an anonymous function I ensure that ‘Pad’ is not globally available and so won’t clash with any existing function of the same name.
A few minor tweaks to the layout and the addition of ‘use strict’ ensures that it validates cleanly in the latest version of JSLint (Edition 2012-12-31).

The source for this function can be downloaded from Gist or Snipplr.
You can also try it out in jsFiddle.


More: