how can i sort this array by date (ISO 8601)?
var myArray = new Array(); myArray[0] = { name:'oldest', date:'2007-01-17T08:00:00Z' } myArray[1] = { name:'newest', date:'2011-01-28T08:00:00Z' } myArray[2] = { name:'old', date:'2009-11-25T08:00:00Z' }
Playground:
http://jsfiddle.net/4tUZt/
Thanks in advance!
To sort a JavaScript array by ISO 8601 date, we can use the JavaScript array's sort method. We have the arr array that we want to sort by the date value. Then we call arr. sort with a callback that compares the strings to compare the date strings directly by their values lexigraphically.
The article is missing one of the best features of iso 8601: it's string form is naturally sortable. You don't need any specific logic for sorting, so e.g. your filesystem will automatically sort files correctly if you prefix them with a iso 8601 date.
Z is the zone designator for the zero UTC offset. "09:30 UTC" is therefore represented as "09:30Z" or "T0930Z". "14:45:15 UTC" would be "14:45:15Z" or "T144515Z". The Z suffix in the ISO 8601 time representation is sometimes referred to as "Zulu time" because the same letter is used to designate the Zulu time zone.
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); });
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
You can avoid creating of dates and by using the built–in lexicographic compare function String.prototype.localeCompare, rather than the ?:
compound operator or other expressions:
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'} ]; // Oldest first console.log( myArray.sort((a, b) => a.date.localeCompare(b.date)) ); // Newest first console.log( myArray.sort((a, b) => -a.date.localeCompare(b.date)) );
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With