Min/Max of dates in an array?
Asked Answered
C

14

163

How can I find out the min and the max date from an array of dates? Currently, I am creating an array like this:

var dates = [];
dates.push(new Date("2011/06/25"))
dates.push(new Date("2011/06/26"))
dates.push(new Date("2011/06/27"))
dates.push(new Date("2011/06/28"))

Is there a built-in function to do this or am I to write my own?

Carl answered 22/8, 2011 at 5:10 Comment(0)
P
180

Code is tested with IE,FF,Chrome and works properly:

var dates=[];
dates.push(new Date("2011/06/25"))
dates.push(new Date("2011/06/26"))
dates.push(new Date("2011/06/27"))
dates.push(new Date("2011/06/28"))
var maxDate=new Date(Math.max.apply(null,dates));
var minDate=new Date(Math.min.apply(null,dates));
Pasteurism answered 22/8, 2011 at 5:46 Comment(7)
To number convertion applied not for string '2011/06/25', but for new Date('2011/06/25'). Number(new Date('2011/06/25'))===1308949200000. Code is tested in Chrome, IE, FFPasteurism
@RobG - What do you mean by "string dates"?Pasteurism
e.g. dates.push('2011/06/05'). Using strings the array can be simply sorted and the first and last member values returned and converted to dates if necessary.Abulia
@Abulia - in the question above array contains Date objects, not "date strings" - response also for Date objects. Using "date strings" is a very bad practic in some cases. Compare next two date strings: "2011/06/05" and "2011/06/05 00:00:00". 1) as strings: ("2011/06/05"==="2011/06/05 00:00:00") : result is false; 2) as Date objects (with convertion to number): Number(new Date("2011/06/05"))===Number(new Date("2011/06/05 00:00:00")) : result is true - is a right result!Pasteurism
@AndrewD. If the dateStrings are consistent, say YYYY/MM/DD HH:MM:SS and there are a lot of strings involved, would you recommend string comparison or Number(new Date(dateString)) comparisons?Stivers
@BlackPanther, I think if all your "date string" has format YYYY/MM/DD HH:MM:SS is no difference how to compare (only difference in algorithm and speed).Pasteurism
what would be the difference between, Math.max.apply(null,dates) and Math.max(...dates)?Stefansson
S
120

Something like:

var min = dates.reduce(function (a, b) { return a < b ? a : b; }); 
var max = dates.reduce(function (a, b) { return a > b ? a : b; });

Tested on Chrome 15.0.854.0 dev

Stupid answered 22/8, 2011 at 5:18 Comment(6)
Array.reduce() not available in IE before IE9. Cool idea though.Colas
Array.reduce() can be implemented with javascript equivalent functionPasteurism
Exactly, read about it in Eloquent Javascript: function foreach(func, array) { for(var i = 0; i != array.length; ++i) { func(array[i]); } } function reduce(combine, base, array) { foreach(function(element) { base = combine(base, element); }, array); return base; }Steelyard
IE <9 can die, and indeed, it now accounts for only 9.3% of global browser use as of April 2013.Lynnett
If there is a null or empty date. min function will not workTrichite
The reduce solution works for string and for Dates objects.Altdorf
E
71

Same as apply, now with spread :

const maxDate = new Date(Math.max(...dates));

(could be a comment on best answer)

Edema answered 16/6, 2019 at 10:55 Comment(1)
For TypeScript, to have type compatibility, the dates should be mapped to a number first, getTime() can be used for this. dates.map(d => d.getTime()).Chaisson
B
46

_.min and _.max work on arrays of dates; use those if you're using Lodash or Underscore, and consider using Lodash (which provides many utility functions like these) if you're not already.

For example,

_.min([
    new Date('2015-05-08T00:07:19Z'),
    new Date('2015-04-08T00:07:19Z'),
    new Date('2015-06-08T00:07:19Z')
])

will return the second date in the array (because it is the earliest).

Bridgid answered 11/4, 2015 at 13:28 Comment(3)
Doesn't directly answer OP's question. OP is asking if a built-in method is available in JavaScript. So, although _.min & _.max can be used to find min or max dates, but is not what the OP is looking for. Also, consideration of a utility library is an opinionated topic.Amphithecium
I respectfully disagree and think this is a useful answer, @Amphithecium - the OP's question as currently worded presumes that either there is a built-in function or he has to write his own, but this isn't true. It seems reasonable to me to point out utility libraries as an alternative to either of the OP's proposed solutions. But your reasoning is defensible, and your vote is your own.Bridgid
Short, concise and works wonderfully for TypeScript as well as it supports Date type.Jaan
B
15

Since dates are converted to UNIX epoch (numbers), you can use Math.max/min to find those:

var maxDate = Math.max.apply(null, dates)
// convert back to date object
maxDate = new Date(maxDate)

(tested in chrome only, but should work in most browsers)

Brainbrainard answered 22/8, 2011 at 5:23 Comment(0)
B
15

ONELINER:

var min= dates.sort((a,b)=>a-b)[0], max= dates.slice(-1)[0];

result in variables min and max, complexity O(nlogn), editable example here. If your array has no-date values (like null) first clean it by dates=dates.filter(d=> d instanceof Date);.

var dates = [];
dates.push(new Date("2011-06-25")); // I change "/" to "-" in "2011/06/25"
dates.push(new Date("2011-06-26")); // because conosle log write dates 
dates.push(new Date("2011-06-27")); // using "-".
dates.push(new Date("2011-06-28"));

var min= dates.sort((a,b)=>a-b)[0], max= dates.slice(-1)[0];

console.log({min,max});
Bolitho answered 6/12, 2018 at 14:34 Comment(0)
K
13

**Use Spread Operators| ES6 **

let datesVar = [ 2017-10-26T03:37:10.876Z,
  2017-10-27T03:37:10.876Z,
  2017-10-23T03:37:10.876Z,
  2015-10-23T03:37:10.876Z ]

Math.min(...datesVar);

That will give the minimum date from the array.

Its shorthand Math.min.apply(null, ArrayOfdates);

Keating answered 26/10, 2017 at 12:33 Comment(3)
If you downvote, please comment. Why is this a bad option? I like the syntax and for small arrays, the performance penalty is negligible.Georgianngeorgianna
I was downvoted. Rudresh's answer is a duplicate of mine above. No idea why people don't like this. It's a single line of code versus many lines.Oden
This returns a number not a date so you have to convert it back to a date. But it is pretty elegant otherwise.Brunhilda
L
4
var max_date = dates.sort(function(d1, d2){
    return d2-d1;
})[0];
Lassitude answered 22/8, 2011 at 5:18 Comment(0)
E
2

if you get max or min date with string type from string date of array,you can try this:

const dates = ["2021-02-05", "2021-05-20", "2021-01-02"]
const min = dates.reduce((acc,date)=>{return acc&&new Date(acc)<new Date(date)?acc:date},'')
const max = dates.reduce((acc,date)=>{return acc&&new Date(acc)>new Date(date)?acc:date},'')
Enunciation answered 27/7, 2021 at 12:6 Comment(0)
D
1

The above answers do not handle blank/undefined values to fix this I used the below code and replaced blanks with NA :

function getMax(dateArray, filler) {
      filler= filler?filler:"";
      if (!dateArray.length) {
        return filler;
      }
      var max = "";
      dateArray.forEach(function(date) {
        if (date) {
          var d = new Date(date);
          if (max && d.valueOf()>max.valueOf()) {
            max = d;
          } else if (!max) {
            max = d;
          }
        }
      });
      return max;
    };
console.log(getMax([],"NA"));
console.log(getMax(datesArray,"NA"));
console.log(getMax(datesArray));

function getMin(dateArray, filler) {
 filler = filler ? filler : "";
  if (!dateArray.length) {
    return filler;
  }
  var min = "";
  dateArray.forEach(function(date) {
    if (date) {
      var d = new Date(date);
      if (min && d.valueOf() < min.valueOf()) {
        min = d;
      } else if (!min) {
        min = d;
      }
    }
  });
  return min;
}

console.log(getMin([], "NA"));
console.log(getMin(datesArray, "NA"));
console.log(getMin(datesArray));

I have added a plain javascript demo here and used it as a filter with AngularJS in this codepen

Dropkick answered 28/12, 2017 at 9:52 Comment(0)
S
1

You can also use date-fns max function if you already have it in your stack:

    import { max } from 'date-fns';
    
    const dates = [
      new Date('2022-01-01'),
      new Date('2023-03-24'),
      new Date('2021-12-31')
    ];
    
    const maxDate = max(...dates);
    
    console.log(maxDate); // Output: Wed Mar 24 2023 00:00:00 GMT-0400 (Eastern Daylight Time)

https://date-fns.org/v2.29.3/docs/max

Shepp answered 24/3, 2023 at 15:52 Comment(0)
O
0

This is a particularly great way to do this (you can get max of an array of objects using one of the object properties): Math.max.apply(Math,array.map(function(o){return o.y;}))

This is the accepted answer for this page: Finding the max value of an attribute in an array of objects

Oden answered 23/5, 2017 at 10:38 Comment(0)
R
0

Using only one loop in typescript you can get min/max date values at the same time:

function minMaxDates(dates: Date[]): {minDate: Date, maxDate: Date} {
    let minDate = new Date(275760, 8, 13);
    let maxDate = new Date(1970, 1, 1);
    dates.map(date => {
        minDate = minDate < date ? minDate : date;
        maxDate = maxDate > date ? maxDate : date;
    });
    return {minDate, maxDate}
};

To call this function:

const {minDate, maxDate} = minMaxDates(dates);

I posted a demo here.

Roundhead answered 27/1, 2023 at 21:21 Comment(0)
S
-2

Using Moment, Underscore and jQuery, to iterate an array of dates.

Sample JSON:

"workerList": [{        
        "shift_start_dttm": "13/06/2017 20:21",
        "shift_end_dttm": "13/06/2017 23:59"
    }, {
        "shift_start_dttm": "03/04/2018 00:00",
        "shift_end_dttm": "03/05/2018 00:00"        
    }]

Javascript:

function getMinStartDttm(workerList) {  
    if(!_.isEmpty(workerList)) {
        var startDtArr = [];
        $.each(d.workerList, function(index,value) {                
            startDtArr.push(moment(value.shift_start_dttm.trim(), 'DD/MM/YYYY HH:mm')); 
         });            
         var startDt = _.min(startDtArr);           
         return start.format('DD/MM/YYYY HH:mm');
    } else {
        return '';
    }   
}

Hope it helps.

Subbasement answered 13/6, 2017 at 15:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.