按ISO 8601日期排序数组

Pet*_*ter 15 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' }
Run Code Online (Sandbox Code Playgroud)

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

提前致谢!

Sco*_*ott 37

按字典顺序排序:

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

'2007-01-17T08:00:00Z' < '2008-01-17T08:00:00Z' === true
Run Code Online (Sandbox Code Playgroud)

所以你要实现:

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);
});
Run Code Online (Sandbox Code Playgroud)

使用JavaScript日期排序:

旧版本的WebKit和Internet Explorer不支持ISO 8601日期,因此您必须创建兼容日期.FireFox和现代WebKit支持它有关Date.parse支持JavaScript的更多信息,请参阅此处:哪些浏览器支持使用Date.parse解析ISO-8601日期字符串

这是一篇非常好的文章,用于创建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));
}
Run Code Online (Sandbox Code Playgroud)

用法:

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;
}
Run Code Online (Sandbox Code Playgroud)

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

  • 这可能是完整的,但这是不必要的.**ISO8601是[设计](https://en.wikipedia.org/wiki/ISO_8601#General_principles)用于字典排序,所以只是''2007-01-17T08:00:00Z'<'2008-01-17T08: 00:00Z'=== true`** (3认同)
  • 小心,这个答案并不完全正确。正如 @icoum 所指出的,如果您的 ISO8601 日期字符串包含时区偏移量或(不太常见)负年份,则字典排序不起作用。因此,如果您不能 100% 确定所有日期都是以通用时间给出的,那么您绝对应该首先从 iso 字符串创建日期对象,然后比较日期对象。 (2认同)

Rob*_*obG 15

您可以避免创建日期并使用内置的字典比较函数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))
);
Run Code Online (Sandbox Code Playgroud)


ico*_*oum 8

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

但是,这仅在所有字符串都使用“Z”或“+00”时区(= UTC)时才有效。以“Z”结尾的日期字符串确实满足 ISO8601 标准,但并非所有 ISO8601 都以“Z”结尾。

因此,要完全符合 ISO8601,您需要使用一些 Date 库(例如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);
});
Run Code Online (Sandbox Code Playgroud)

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

有关 ISO8601 标准的更多信息:此处

  • 嗨,我必须不同意。例如,在 Web 应用程序中,您可以比较从 API 获取的某些日期和您刚刚在 Web 应用程序中选择的某些日期。第二个肯定会使用计算机的本地时区,这可能与 API 的不同。您还可以比较从使用不同时区的 2 个不同 API 获得的日期。 (2认同)

Dzi*_*owy 5

我会这样:

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

function byDate (a, b) {
    if (a.date < b.date) return -1; 
    if (a.date > b.date) return 1; 
    return 0;  
}

const newArray = myArray.sort(byDate);


console.clear();
console.dir(myArray);
console.dir(newArray);
Run Code Online (Sandbox Code Playgroud)

  • 实际上,在这种情况下,他只是按字母顺序排序,这似乎应该可以+1 (2认同)