165

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?

14 Answers 14

181

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));
Sign up to request clarification or add additional context in comments.

7 Comments

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, FF
@RobG - What do you mean by "string dates"?
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.
@RobG - 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!
what would be the difference between, Math.max.apply(null,dates) and Math.max(...dates)?
|
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

6 Comments

Array.reduce() not available in IE before IE9. Cool idea though.
Array.reduce() can be implemented with javascript equivalent function
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; }
IE <9 can die, and indeed, it now accounts for only 9.3% of global browser use as of April 2013.
The reduce solution works for string and for Dates objects.
|
75

Same as apply, now with spread :

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

(could be a comment on best answer)

1 Comment

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()).
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).

3 Comments

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.
I respectfully disagree and think this is a useful answer, @detj - 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.
Short, concise and works wonderfully for TypeScript as well as it supports Date type.
16

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)

Comments

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});

Comments

14

**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);

3 Comments

If you downvote, please comment. Why is this a bad option? I like the syntax and for small arrays, the performance penalty is negligible.
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.
This returns a number not a date so you have to convert it back to a date. But it is pretty elegant otherwise.
4
var max_date = dates.sort(function(d1, d2){
    return d2-d1;
})[0];

Comments

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},'')

Comments

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

Comments

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

Comments

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

Comments

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.

Comments

-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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.