Min / Max de dates dans un tableau?


106

Comment puis-je connaître la date minimale et la date maximale à partir d'un tableau de dates? Actuellement, je crée un tableau comme celui-ci:

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

Existe-t-il une fonction intégrée pour faire cela ou dois-je écrire la mienne?

Réponses:


137

Le code est testé avec IE, FF, Chrome et fonctionne correctement:

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

1
La conversion en nombre ne s'applique pas à la chaîne '2011/06/25', mais à la nouvelle date ('2011/06/25'). Numéro (nouvelle date ('2011/06/25')) === 1308949200000. Le code est testé dans Chrome, IE, FF
— Andrew D.

@RobG - Qu'entendez-vous par "dates de chaîne"?
— Andrew D.

par exemple dates.push('2011/06/05'). En utilisant des chaînes, le tableau peut être simplement trié et les premières et dernières valeurs de membre renvoyées et converties en dates si nécessaire.
— RobG

10
@RobG - dans la question ci-dessus, le tableau contient des objets Date, pas des "chaînes de date" - réponse également pour les objets Date. L'utilisation de "chaînes de date" est une très mauvaise pratique dans certains cas. Comparez les deux chaînes de date suivantes: "2011/06/05" et "2011/06/05 00:00:00". 1) sous forme de chaînes: ("2011/06/05" === "2011/06/05 00:00:00"): le résultat est faux; 2) en tant qu'objets Date (avec conversion en nombre): Number (new Date ("2011/06/05")) === Number (new Date ("2011/06/05 00:00:00")): résultat est vrai - est un bon résultat!
— Andrew D.

@AndrewD. Si les datesStrings sont cohérentes, disons YYYY/MM/DD HH:MM:SSet qu'il y a beaucoup de chaînes impliquées, recommanderiez-vous une comparaison ou des Number(new Date(dateString))comparaisons de chaînes ?
— BlackPanther

83

Quelque chose comme:

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

Testé sur Chrome 15.0.854.0 dev


Array.reduce()non disponible dans IE avant IE9. Bonne idée cependant.
— jfriend00

1
Array.reduce () peut être implémenté avec une fonction équivalente javascript
— Andrew D.

Exactement, lisez-le en Javascript éloquent :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; }
— blaze le

1
IE <9 peut mourir, et en fait, il ne représente plus que 9,3% de l'utilisation mondiale des navigateurs en avril 2013.
— wprl

3
La solution de réduction fonctionne pour la chaîne et pour les objets Dates.
— Benoit

33

_.minet _.maxtravailler sur des tableaux de dates; utilisez-les si vous utilisez Lodash ou Underscore, et envisagez d'utiliser Lodash (qui fournit de nombreuses fonctions utilitaires comme celles-ci) si vous ne l'êtes pas déjà.

Par exemple,

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

renverra la deuxième date dans le tableau (car c'est la plus ancienne).


3
Ne répond pas directement à la question d'OP. OP demande si une méthode intégrée est disponible en JavaScript. Donc, bien que _.min & _.max puissent être utilisés pour trouver des dates min ou max, mais ce n'est pas ce que l'OP recherche. En outre, l'examen d'une bibliothèque utilitaire est un sujet d'opinion.
— detj

13
Je suis respectueusement en désaccord et je pense que c'est une réponse utile, @detj - la question du PO, telle qu'elle est actuellement formulée, suppose qu'il y a une fonction intégrée ou qu'il doit écrire la sienne, mais ce n'est pas vrai. Il me semble raisonnable d'indiquer les bibliothèques utilitaires comme une alternative à l'une ou l'autre des solutions proposées par l'OP. Mais votre raisonnement est défendable et votre vote est le vôtre.
— Mark Amery

16

Identique à appliquer, maintenant avec propagation :

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

(pourrait être un commentaire sur la meilleure réponse)


12

Puisque les dates sont converties en epoch UNIX (nombres), vous pouvez utiliser Math.max / min pour les trouver:

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

(testé uniquement dans Chrome, mais devrait fonctionner dans la plupart des navigateurs)


8

** Utiliser les opérateurs de diffusion | 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);

Cela donnera la date minimale du tableau.

Son raccourci Math.min.apply (null, ArrayOfdates);


1
Si vous êtes contre, veuillez commenter. Pourquoi est-ce une mauvaise option? J'aime la syntaxe et pour les petits tableaux, la pénalité de performance est négligeable.
— GijsjanB

1
J'ai été critiqué. La réponse de Rudresh est une copie de la mienne ci-dessus. Je ne sais pas pourquoi les gens n'aiment pas ça. C'est une seule ligne de code contre plusieurs lignes.

3
Cela renvoie un nombre et non une date, vous devez donc le reconvertir en date. Mais c'est assez élégant autrement.
— Tomáš Hübelbauer

6

ONELINER :

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

résultent en variables minet max, complexité O (nlogn) , exemple modifiable ici . Si votre tableau a des valeurs sans date (comme null), nettoyez-le d'abord dates=dates.filter(d=> d instanceof Date);.


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

1

Les réponses ci-dessus ne gèrent pas les valeurs vides / non définies pour résoudre ce problème.J'ai utilisé le code ci-dessous et remplacé les blancs par 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));

J'ai ajouté une démo javascript simple ici et je l'ai utilisée comme filtre avec AngularJS dans ce codepen



-2

Utilisation de Moment , Underscore et jQuery , pour parcourir un tableau de dates.

Exemple de 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 '';
    }   
}

J'espère que ça aide.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.