Tasos
Tasos

Reputation: 7567

Sort an array of arrays by date in Javascript

I have an array of arrays which the first field is a date (in string format). I want to sort them by the date (asceding), so I can use it for further calculations.

I identify two tasks on my problem. First, parse strings as dates and then sort.

a = new Date(Date.parse('1/11/2014 13:42:54'));
console.log(a)

Return 11th of January whereas I need 1st of November

Then, I the sorting should work like this:

function compare(a,b) {
  if (a[0] < b[0])
     return -1;
  if (a[0] > b[0])
    return 1;
  return 0;
}

myarray.sort(compare);

So, how can I solve the problem with the dates to make it works on sorting function?

Upvotes: 4

Views: 1773

Answers (4)

CuriousMind
CuriousMind

Reputation: 34135

With moment.js you can create a moment object using the String+Format constructor

moment('1/11/2014 13:42:54', 'DD/MM/YYYY HH:mm:ss')

so, if you have an array of arrays which the first field is a date (in string format):

array_of_arrays = [
  ['1/11/2014 13:42:54', 'val'],
  ['2/11/2014 13:42:54', true]
];

for(array in array_of_arrays){
     epoch = moment(array.shift,'DD/MM/YYYY HH:mm:ss').unix();
     array.unshift(epoch);
 }

now, you can just do new Date(epoch) as instead of complex date objects, we have Unix Epoch which can be easily sorted with inbuid Array.sort something like this

function Comparator(a,b){
 if (a[0] < b[0]) return -1;
 if (a[0] > b[0]) return 1;
 return 0;
}
array_of_arrays.sort(Comparator);

so now you have array_of_arrays sorted as per date

Lastly, if you need more precise answer than this, please share some more sample code.

Upvotes: 1

thefourtheye
thefourtheye

Reputation: 239443

Just capture the date and month part, swap them and do Date.parse and new Date, like this

function getFormattedDate(dateString) {
    var result = dateString.replace(/(\d+)\/(\d+)(.*)/, function (m, g1, g2, g3) {
        return g2 + "/" + g1 + g3;
    });

    return new Date(Date.parse(result));
}

console.log(getFormattedDate('1/11/2014 13:42:54'));
// Sat Nov 01 2014 13:42:54 GMT+0000 (GMT)

Here, the regular expression, (\d+)\/(\d+)(.*) will capture three parts of the string, first (\d+) captures the date part followed by / (escaped as \/) and the month part with another (\d+) and the rest of the string is captured with (.*). Then we return a new string by swapping the positions of g2 and g1 (month and date part).

Note: If all you are trying to do is sorting, then you don't need to create a new Date object. You can simply use the result of Date.parse which is epoch time, like this

function getEpochTime(dateString) {
    var result = dateString.replace(/(\d+)\/(\d+)(.*)/, function (m, g1, g2, g3) {
        return g2 + "/" + g1 + g3;
    });

    return Date.parse(result);
}

function comparator(firstDate, secondDate) {
    return getEpochTime(firstDate) - getEpochTime(secondDate);
}

and then sort like this

var arr = ['3/11/2014 13:42:54',
    '2/11/2014 13:42:54',
    '1/12/2014 13:42:54',
    '1/11/2014 13:43:54'
];

arr.sort(comparator);

console.log(arr);

would give you

[ '1/11/2014 13:43:54',
  '2/11/2014 13:42:54',
  '3/11/2014 13:42:54',
  '1/12/2014 13:42:54' ]

Upvotes: 1

ninhjs.dev
ninhjs.dev

Reputation: 8543

This is problem:

a = new Date(Date.parse('1/11/2014 13:42:54'));
console.log(a)

Return 11th of January whereas I need 1st of November`

Your date format is dd/mm/yyy; Date.parse('1/11/2014 13:42:54') accepts mm/dd/yyyy

Try a date parsing as following:

function parseDate(str) {
    var ds = str.match(/(\d+)\/(\d+)\/(\d+)\s+(\d+):(\d+):(\d+)/);
    // Convert to format: mm/dd/yyyy
    return new Date(ds[3], ds[2] - 1, // month is 0-based
                ds[1], ds[4], ds[5], ds[6]);
}

var arr = [parseDate('3/11/2014 13:42:54'),
  parseDate('2/11/2014 13:42:54'),
  parseDate('1/12/2014 13:42:54'),
  parseDate('1/11/2014 13:43:54')
];

arr.sort();

Or:

function parseDate(str) {
    var ds = str.match(/(\d+)\/(\d+)\/(\d+)\s+(\d+):(\d+):(\d+)/);
    // Convert to format: mm/dd/yyyy
    return new Date(ds[3], ds[2] - 1, // month is 0-based
                ds[1], ds[4], ds[5], ds[6]);
}

var arr = ['3/11/2014 13:42:54',
  '2/11/2014 13:42:54',
  '1/12/2014 13:42:54',
  '1/11/2014 13:43:54'
];


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

Upvotes: 0

hindmost
hindmost

Reputation: 7195

If your dates are in ISO format you can use such a code:

myarray.sort(function (a, b) {
    return (new Date(a[0])).getTime() - (new Date(b[0])).getTime();
});

Upvotes: 3

Related Questions