javascript 按 ISO 8601 日期对数组进行排序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12192491/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 15:33:10  来源:igfitidea点击:

Sort array by ISO 8601 date

javascriptarrayssortingiso8601

提问by Peter

how can i sort this array by date (ISO 8601)?

我如何按日期排序这个数组(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/

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

Thanks in advance!

提前致谢!

回答by Scott

Sort Lexicographically:

按字典排序:

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

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

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

使用 JavaScript 日期排序:

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 thoughSee here for more information about Date.parse support JavaScript: Which browsers support parsing of ISO-8601 Date String with Date.parse

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

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

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

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

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

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

回答by RobG

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:

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

回答by Dziad Borowy

I'd go with this:

我会这样做:

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

回答by nbrooks

http://jsfiddle.net/4tUZt/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;
}

?

?

回答by Danil Speransky

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

演示: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));

?

?

回答by rjmunro

ISO8601 is designed to sort correctly as plain text, so in general, a normal sort will do.

ISO8601 旨在作为纯文本正确排序,因此一般而言,正常排序即可。

To sort by a specific key of objects in an array, you need to specify a comparison function to the sort()method. In many other languages, these are easy to write using the cmpfunction, but JS doesn't have a built in cmpfunction, so I find it easiest to write my own.

要按数组中对象的特定键进行排序,您需要为该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. I would write my array using JSON-like syntax, like this:

Ps 我会使用类似 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' }
];

回答by icoum

Be careful, the accepted answer now advises to sort our dates lexicographically.

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

However, this will only work if all your strings use the 'Z' or '+00' timezone(= UTC). Date strings ending with 'Z' do satisfy ISO8601 standard, but all ISO8601 do not end with 'Z'.

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

Thus, to be fully ISO8601 compliant, you need to parse your strings with some Date library (e.g. Javascript Dateor Moment.js), and compare these objects. For this part, you can check Scott's answer that also covers browsers incompatible with ISO8601.

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

My simple example with Javascript Date (works on any not-too-old browser) :

我使用 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);
});

Downside : This is slower than just comparing strings lexicographically.

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

More info about ISO8601 standard : here.

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