Мин. / Макс. Дат в массиве?

Как я могу узнать минимальную и максимальную дату из массива дат? В настоящее время я создаю массив следующим образом:

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"))

Есть ли встроенная функция для этого или я пишу свою собственную?

15 ответов

Код протестирован с IE,FF,Chrome и работает правильно:

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

Что-то вроде:

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

Протестировано на Chrome 15.0.854.0 dev

То же, что и применить, теперь со спредом:

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

(может быть комментарий к лучшему ответу)

_.min а также _.max работа над массивами дат; используйте их, если вы используете Lodash или Underscore, и рассмотрите возможность использования Lodash (который предоставляет множество подобных утилит), если вы этого еще не сделали.

Например,

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

вернет вторую дату в массиве (потому что она самая ранняя).

Поскольку даты конвертируются в эпоху UNIX (числа), вы можете использовать Math.max/min, чтобы найти их:

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

(протестировано только в Chrome, но должно работать в большинстве браузеров)

ONELINER:

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

результат в переменных min а также max, сложность O (nlogn), редактируемый пример здесь. Если ваш массив имеет значения без даты (например, null) сначала почисти 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});

** Используйте операторы спреда | 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);

Это даст минимальную дату из массива.

Его сокращение Math.min.apply(null, ArrayOfdates);

function sortDates(a, b)
{
    return a.getTime() - b.getTime();
}

var dates = [];

dates.push(new Date("2011/06/26"))
dates.push(new Date("2011/06/28"))
dates.push(new Date("2011/06/25"))
dates.push(new Date("2011/06/27"))

var sorted = dates.sort(sortDates);
var minDate = sorted[0];
var maxDate = sorted[sorted.length-1];

Демо: http://jsfiddle.net/AlienWebguy/CdXTB/

var max_date = dates.sort(function(d1, d2){
    return d2-d1;
})[0];

если вы получаете максимальную или минимальную дату со строковым типом из строковой даты массива, вы можете попробовать следующее:

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

Вы также можете использоватьdate-fns maxфункция, если она уже есть в вашем стеке:

          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

Приведенные выше ответы не обрабатывают пустые / неопределенные значения, чтобы исправить это. Я использовал приведенный ниже код и заменил пробелы на 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));

Я добавил здесь простую демонстрацию javascript и использовал ее как фильтр с AngularJS в этом коде

Используя только один цикл в машинописном тексте, вы можете одновременно получать минимальные/максимальные значения даты:

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

Чтобы вызвать эту функцию:

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

Я разместил демо здесь .

Это особенно хороший способ сделать это (вы можете получить максимум из массива объектов, используя одно из свойств объекта): Math.max.apply(Math,array.map(function(o){return o.y;}))

Это приемлемый ответ для этой страницы: поиск максимального значения атрибута в массиве объектов

Использование Moment, Underscore и jQuery для итерации массива дат.

Образец 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 '';
    }   
}

Надеюсь, поможет.

Другие вопросы по тегам