Sort Array by ISO 8601 date

Sort Lexicographically:

As @kdbanman points out, ISO8601See General principles was designed for lexicographical sort. As such the ISO8601 string representation can be sorted like any other string, and this will give the expected order.

'2007-01-17T08:00:00Z' < '2008-01-17T08:00:00Z' === true

So you would implement:

var myArray = [
    { name:'oldest', date:'2007-01-17T08:00:00Z' },
    { name:'newest', date:'2011-01-28T08:00:00Z' },
    { name:'old',    date:'2009-11-25T08:00:00Z' }
];

myArray.sort(function(a, b) {
    return (a.date < b.date) ? -1 : ((a.date > b.date) ? 1 : 0);
});

Sort using JavaScript Date:

Older versions of WebKit and Internet Explorer do not support ISO 8601 dates, so you have to make a compatible date. It is supported by FireFox, and modern WebKit though See here for more information about Date.parse support JavaScript: Which browsers support parsing of ISO-8601 Date String with Date.parse

Here is a very good article for creating a Javascript ISO 8601 compatible date, which you can then sort like regular javascript dates.

http://webcloud.se/log/JavaScript-and-ISO-8601/

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

Usage:

console.log(myArray.sort(sortByDate));  

function sortByDate( obj1, obj2 ) {
    var date1 = (new Date()).setISO8601(obj1.date);
    var date2 = (new Date()).setISO8601(obj2.date);
    return date2 > date1 ? 1 : -1;
}

Updated usage to include sorting technique credit @nbrooks

Leave a Comment