2

There is an array:

var a = new Array();

It contains date entries like this: '2012-09-12 09:20', etc

I need to find minimum and maximum dates using javascript. This code does not work with time values.

var minT = Math.min.apply(Math, a);
var maxT = Math.max.apply(Math, a);

How can I solve this problem in javascript? It seems to be quite complex as I'm not very experienced in this language.

piokuc
  • 25,594
  • 11
  • 72
  • 102
You Kuper
  • 1,113
  • 7
  • 18
  • 38

5 Answers5

5

If your array contains Date objects, then this should work. If it just contains strings like '2012-09-12 09:20', then you can sort them, and get the 1st and last elements.

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

var maxT = a[a.length-1];
var minT = a[0];
gen_Eric
  • 223,194
  • 41
  • 299
  • 337
  • Nice, except that the order of items in the array is reorganized and that it creates a lot of objects (could be a problem if there are many dates) – some Sep 12 '12 at 15:10
  • @some: Might not be the best solution, but it was the 1st think I could think of :-) – gen_Eric Sep 12 '12 at 15:11
  • 2
    sorting the array is not really efficient - `O(n log n)` while min&max need `O(2n)`. Also, your sort method creates two `Date` objects in each comparison - while an alphanumerical sort would have the same result. – Bergi Sep 12 '12 at 15:13
  • @Bergi: An alphanumeric sort would only work if the dates were in the same format. This will work for all formats. Also, I know it's not very efficient, it's just all I could think of :-P – gen_Eric Sep 12 '12 at 15:26
  • 1
    @Bergi Alphanumeric sort only works if the pars are in the right order Y-M-D H:M:S, not for D/M/Y or M/D/Y. – some Sep 12 '12 at 15:39
  • Not sure, but `Date.parse` may be better than `new Date`. – gen_Eric Sep 12 '12 at 15:50
  • @Bergi I'm aware of that the one date that OP posted was in that format. I'm not surprised if all of OP dates is in that format. However, it is not a generic solution. My comment was just a reminder that it only works in with the right format. – some Sep 12 '12 at 19:05
  • Is `getTime` easier/clearer in the comparator, i.e. `a.sort(function(a, b) { return a.getTime() - b.getTime(); })` – patricksurry Apr 29 '15 at 01:03
  • @patricksurry: If you have an array of `Date` objects, you can just do `return a-b;`. `Date`s are converted automatically using `.getTime()` (for proof enter `+new Date()` in your console). – gen_Eric Apr 29 '15 at 20:50
  • 1
    Hmm. Why does `[new Date('2015-01-01'), new Date('2015-03-01'), new Date('2015-02-01')].sort()` sort from largest to smallest (in Chrome at least), whereas `[new Date('2015-01-01'), new Date('2015-03-01'), new Date('2015-02-01')].sort(function(a,b) { return a-b; })` sorts correctly in ascending order? – patricksurry Apr 30 '15 at 16:21
  • @patricksurry: According to the docs for `.sort`: If *compareFunction* is not supplied, elements are sorted by converting them to strings and comparing strings in Unicode code point order. This is why it doesn't sort as you expect. – gen_Eric Apr 30 '15 at 23:16
  • 1
    Ah, thanks, that makes sense. Too many implicit conversions. Sorry for taking this off topic. – patricksurry May 01 '15 at 10:25
3

Math.min/max only compares numbers, not strings. Don't use them to represent the dates, but use Date objects - they will be compared by their internal timestamp number. Still, the max/min will return that internal number, so you would need to convert it back to a Date (see Min/Max of dates in an array?):

However, if you want to use the strings or can't use the recreated Date, you will need to run manually through the array - either with a for-loop, or the ES5.1-only iterator method .reduce():

var min = datestrings.reduce(function(min, cur) {
    return cur < min ? cur : min;
});

// is equivalent to
var min = datestrings[0];
for (var i=1; i<datestrings.length; i++)
    if (datestrings[i] < min)
        min = datestrings[i];

If your code does not need to be efficient, you also just can sort the array and get the first and last values. The default alphanumeric sorting will do it for your date format, so this is really simple:

datestrings.sort();
var min = datestrings[0],
    max = datestrings[datestrings.lengh-1];
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
1

This should do it:

var maxT=new Date(Math.max.apply(null,a));
var minT=new Date(Math.min.apply(null,a));

If you must work with strings you could define a function:

function maxDate(data){
    var max = '';
    for(var i=0; i<data.length; i++)
        if(data[i]>max)
            max=data[i];
    return max;
}

And then:

var maxT=maxDate(a);

DISCLAIMER: This second method will only work if all the date strings are in the same format, if you have different format dates in your array you will not be able to use this function.

mornaner
  • 2,424
  • 2
  • 27
  • 39
1

Try this:

var maxDate=new Date(Math.max.apply(null,dates));
var minDate=new Date(Math.min.apply(null,dates));

I found it on an earlier question

Community
  • 1
  • 1
Luigi Siri
  • 2,068
  • 2
  • 19
  • 27
0

Is the array filled with Date objects? If so, compare them using them, and sort them using one of the many known algorithms.

If not, recreate the array with Date objects, one for each of them, and do as I said above, by ordering the array.

seth
  • 1,401
  • 1
  • 17
  • 28