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?

Légende
la source

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));
Andrew D.
la source
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


la source
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).

Mark Amery
la source
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)

lvd
la source
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)

Ricardo Tomasi
la source
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);

Rudresh Ajgaonkar
la source
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);.

Kamil Kiełczewski
la source
2
var max_date = dates.sort(function(d1, d2){
    return d2-d1;
})[0];
wong2
la source
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

Samdeesh
la source
-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.

Siva Anand
la source