admin管理员组

文章数量:1356290

I am trying to sort an array which contains dates in string format (dd-mmm-yy), using the sort() function:

var array = ["1-jun-15", "1-feb-15", "1-apr-15", "1-may-15", "1-jan-15", "1-mar-15"];

array.sort(function(a, b) {
  return new Date(a).getTime() - new Date(b).getTime();
});

But no success.

What's going wrong here? Here is the JSFiddle.

EDIT: While the sorting problem was solved with small correction, the primary issue is cross-browser support, which many of the answers below have differently addressed.

I am trying to sort an array which contains dates in string format (dd-mmm-yy), using the sort() function:

var array = ["1-jun-15", "1-feb-15", "1-apr-15", "1-may-15", "1-jan-15", "1-mar-15"];

array.sort(function(a, b) {
  return new Date(a).getTime() - new Date(b).getTime();
});

But no success.

What's going wrong here? Here is the JSFiddle.

EDIT: While the sorting problem was solved with small correction, the primary issue is cross-browser support, which many of the answers below have differently addressed.

Share Improve this question edited Nov 29, 2016 at 18:34 Rishabh asked Nov 29, 2016 at 12:43 RishabhRishabh 90011 silver badges31 bronze badges 3
  • 5 Those aren't valid dates – adeneo Commented Nov 29, 2016 at 12:43
  • 2 a and b are strings, what do you expect a.date and b.date to be? – Teemu Commented Nov 29, 2016 at 12:50
  • Sorry it was a mistake @Teemu ! It will be a and b instead of the property accessors. Thanks! – Rishabh Commented Nov 29, 2016 at 12:57
Add a ment  | 

6 Answers 6

Reset to default 6

You could split the date strings and use an object for the month values.

This proposal sorts first by year, then by month with the object and then by day.

var array = ["1-jun-15", "1-feb-15", "1-apr-15", "1-may-15", "1-jan-15", "1-mar-15"],
    MONTHS = { jan: 1, feb: 2, mar: 3, apr: 4, may: 5, jun: 6, jul: 7, aug: 8, sep: 9, oct: 10, nov: 11, dec: 12 };

array.sort(function (a, b) {
    var aa = a.split('-'),
        bb = b.split('-');

    return aa[2] - bb[2] || MONTHS[aa[1]] - MONTHS[bb[1]] || aa[0] - bb[0];
});

console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }

You try to get date property from a and b in the parator, but it's just a strings. So you need to parse it (Date.parse(a) or just new Date(a)).

Here is fixed jsfiddle.

Those aren't valid dates, and the strings have no date property, so every sort iteration just pares NaN instead of dates

Some browsers may be able to parse 1-jun-15, but it is not a IETF-pliant date, and there's no guarantee the javascript engine will know what to do with a date in that format.

As a matter of fact, a little testing in IE and Firefox shows they fail to parse that format all together, while Chrome has no issues with it, and that's why a standards pliant date or multiple arguments should always be passed to new Date.

You'll have to parse the dates yourself

var array = ["1-jun-15", "1-feb-15", "1-apr-15", "1-may-15", "1-jan-15", "1-mar-15"];

var months = [
	"jan", "feb","mar","apr","may","jun","jul","aug","sep","oct","nov", "dec"
];

function parse(date) {
    var parts = date.split('-');
    return new Date('20'+parts[2], months.indexOf(parts[1]), parts[0]);
}

array.sort(function(a, b) {
    return parse(a).getTime() - parse(b).getTime();
});

console.log(array);

You need three steps:

  1. Convert the dates
  2. Sort the dates
  3. Convert the dates back again

Working example:

var dateArray = ["1-jun-15", "1-feb-15", "1-apr-15", "1-may-15", "1-jan-15", "1-mar-15"];

console.log(dateArray);

// STEP ONE - CONVERT THE ARRAY ITEMS

for (var i = 0; i < dateArray.length; i++) {

    var tempDateArray = dateArray[i].split('-');

// Convert the year into a 4-digit number 

    var year = '20' + tempDateArray[2];

// Convert the month into a 2-digit number

    var month = tempDateArray[1];

    switch(month) {
        case ('jan') : month = '01'; break;
        case ('feb') : month = '02'; break;
        case ('mar') : month = '03'; break;
        case ('apr') : month = '04'; break;
        case ('may') : month = '05'; break;
        case ('jun') : month = '06'; break;
        case ('jul') : month = '07'; break;
        case ('aug') : month = '08'; break;
        case ('sep') : month = '09'; break;
        case ('oct') : month = '10'; break;
        case ('nov') : month = '11'; break;
        case ('dec') : month = '12'; break;
    }

// Convert the date into a 2-digit number  

    var date = tempDateArray[0];

    if (date < 2) {
        date = '0' + date;
    }

// Recreate each array item as an 8-digit integer

dateArray[i] = year + month + date;

}

console.log(dateArray);


// STEP TWO  - SORT THE ARRAY ITEMS

dateArray.sort(function(a, b){return a-b});

console.log(dateArray);


// STEP THREE - CONVERT THE ARRAY ITEMS BACK AGAIN

for (var i = 0; i < dateArray.length; i++) {

    // Convert the date back again

    var date = dateArray[i].substring(6);

    if (date.substring(0,1) === '0') {
        var date = date.substring(1);
    }


    // Convert the month back again

    var month = dateArray[i].substring(4,6);

    switch(month) {
        case ('01') : month = 'jan'; break;
        case ('02') : month = 'feb'; break;
        case ('03') : month = 'mar'; break;
        case ('04') : month = 'apr'; break;
        case ('05') : month = 'may'; break;
        case ('06') : month = 'jun'; break;
        case ('07') : month = 'jul'; break;
        case ('08') : month = 'aug'; break;
        case ('09') : month = 'sep'; break;
        case ('10') : month = 'oct'; break;
        case ('11') : month = 'nov'; break;
        case ('12') : month = 'dec'; break;
    }


    // Convert the year back again

    var year = dateArray[i].substring(2,4);

    dateArray[i] = date + '-' + month + '-' + year;

}

console.log(dateArray);

An easy approach would be to convert the dates into Unix Timestamps, sort them, and then convert back to your original date format. Then you don't have to worry about doing string parisons on the months.

You need to convert your date string into a valid date, then pare the timestamps.

var array = ["1-jun-15", "1-feb-15", "1-apr-15", "1-may-15", "1-jan-15", "1-mar-15"];
const months = ['jan', 'feb', 'mar', 'apr', 'may', 'jun']

const strToDate = str => {
  const params = str.split('-')
  params[0] = parseInt(params[0])
  params[1] = months.indexOf(params[1])
  params[2] = parseInt(params[2]) + 2000
  return new Date(...params.reverse())
  
}
array.sort(function(a, b) {
  return strToDate(a).getTime() - strToDate(b).getTime();
});

console.log(array)

本文标签: javascriptsort an array containing dates in ddmmmyy formatStack Overflow