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
Sort array by ISO 8601 date
提问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
$(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 cmp
function, but JS doesn't have a built in cmp
function, 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 Date或Moment.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 标准的更多信息:此处。