按ISO 8601日期排序数组

时间:2012-08-30 08:05:28

标签: javascript arrays sorting iso8601

我如何按日期排序此数组(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' }

游乐场:
http://jsfiddle.net/4tUZt/

提前致谢!

7 个答案:

答案 0 :(得分:26)

按字典顺序排序:

正如@kdbanman所指出的那样,ISO8601 参见一般原则 是专为字典排序而设计的。因此,ISO8601字符串表示可以像任何其他字符串一样进行排序,这将给出预期的顺序。

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

所以你要实现:

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

使用JavaScript日期排序:

较旧版本的WebKit和Internet Explorer不支持ISO 8601日期,因此您必须创建兼容日期。它受FireFox和现代WebKit支持有关Date.parse支持的更多信息,请参阅此处JavaScript: Which browsers support parsing of ISO-8601 Date String with Date.parse

这是一篇非常好的文章,用于创建Javascript ISO 8601兼容日期,然后您可以按照常规javascript日期进行排序。

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

用法:

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

更新了用法以包括排序技术信用@nbrooks

答案 1 :(得分:3)

我会这样做:

console.clear();

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' }

console.dir(myArray);

var newArray = myArray.sort(function(a,b){ 
    if (a.date < b.date) return -1; 
    else if (a.date > b.date) return 1; 
    else return 0;
});

console.dir(newArray);

答案 2 :(得分:2)

http://jsfiddle.net/4tUZt/2/

$(document).ready(function()
{ 
    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' }];

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

// Stable, ascending sort (use < for descending)
function sortByDate( obj1, obj2 ) {
    return new Date(obj2.date) > new Date(obj1.date) ? 1 : -1;
}

答案 3 :(得分:2)

通过使用内置的词典比较功能String.prototype.localeCompare而不是?:复合运算符或其他表达式,可以避免创建日期:

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

答案 4 :(得分:1)

演示:http://jsfiddle.net/4tUZt/4/

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

var sortFunction = function (a, b) {
  return Date.parse(b.date) - Date.parse(a.date);
};

/* or

var sortFunction = function (a, b) {
  return new Date(b.date) - new Date(a.date);
};

*/

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

答案 5 :(得分:1)

ISO8601旨在正确排序为纯文本,因此通常情况下会进行正常排序。

要按数组中对象的特定键进行排序,需要为sort()方法指定比较函数。在许多其他语言中,使用cmp函数很容易编写,但JS没有内置cmp函数,因此我发现编写自己的函数最简单。

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' }

// cmp helper function - built in to many other languages
var cmp = function (a, b) {
    return (a > b) ? 1 : ( (a > b) ? -1 : 0 );
}

myArray.sort(function (a,b) { return cmp(a.date, b.date) });

P.S。我会使用类似JSON的语法编写我的数组,如下所示:

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' }
];

答案 6 :(得分:0)

请注意,现在接受的答案建议按字典顺序对我们的日期进行排序。

但是,仅当您所有的字符串都使用“ Z”或“ +00”时区时,此功能才起作用(= UTC)。 以'Z'结尾的日期字符串确实符合ISO8601标准,但是所有ISO8601都不以'Z'结尾。

因此,要完全符合ISO8601,您需要使用某些日期库(例如Javascript DateMoment.js)解析字符串,然后比较这些对象。 对于这一部分,您可以检查Scott的答案,该答案还涵盖了与ISO8601不兼容的浏览器。

我的Javascript Date简单示例(可在任何不太旧的浏览器上使用):

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

myArray.sort(function(a, b) {
    return new Date(a.date) - new Date(b.date);
});

缺点:这比按字典顺序比较字符串要慢。

有关ISO8601标准的更多信息:here