Min / Max di date in un array?


106

Come posso scoprire la data minima e quella massima da una serie di date? Attualmente, sto creando un array come questo:

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

C'è una funzione incorporata per farlo o devo scrivere la mia?

Risposte:


137

Il codice è testato con IE, FF, Chrome e funziona correttamente:

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
Alla conversione del numero applicata non per la stringa "2011/06/25", ma per la nuova data ("2011/06/25"). Numero (nuova data ('2011/06/25')) === 1308949200000. Il codice è testato in Chrome, IE, FF
Andrew D.

@ RobG - Cosa intendi per "date stringa"?
Andrew D.

ad es dates.push('2011/06/05'). Utilizzando le stringhe, l'array può essere semplicemente ordinato e il primo e l'ultimo valore del membro restituiti e convertiti in date, se necessario.
RobG

10
@ RobG - nella domanda sopra l'array contiene oggetti Date, non "stringhe di data" - risposta anche per gli oggetti Date. Usare "stringhe di data" in alcuni casi è una pessima pratica. Confronta le due stringhe di data successive: "2011/06/05" e "2011/06/05 00:00:00". 1) come stringhe: ("2011/06/05" === "2011/06/05 00:00:00"): il risultato è falso; 2) come oggetti Date (con conversione in numero): Number (new Date ("2011/06/05")) === Number (new Date ("2011/06/05 00:00:00")): risultato è vero - è un risultato giusto!
Andrew D.

@AndrewD. Se le dateStrings sono coerenti, ad esempio YYYY/MM/DD HH:MM:SSe sono coinvolte molte stringhe, consiglieresti il ​​confronto o il Number(new Date(dateString))confronto tra stringhe ?
BlackPanther

83

Qualcosa di simile a:

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

Testato su Chrome 15.0.854.0 dev


Array.reduce()non disponibile in IE prima di IE9. Bella idea però.
jfriend00

1
Array.reduce () può essere implementato con la funzione equivalente a javascript
Andrew D.

Esatto, leggilo 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; }
blaze

1
IE <9 può morire e, infatti, ora rappresenta solo il 9,3% dell'utilizzo globale del browser ad aprile 2013.
wprl

3
La soluzione reduce funziona per string e per gli oggetti Dates.
Benoit

33

_.mine _.maxlavorare su array di date; usali se stai usando Lodash o Underscore e considera l'utilizzo di Lodash (che fornisce molte funzioni di utilità come queste) se non lo sei già.

Per esempio,

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

restituirà la seconda data nell'array (perché è la prima).


3
Non risponde direttamente alla domanda di OP. OP chiede se un metodo integrato è disponibile in JavaScript. Quindi, sebbene _.min e _.max possano essere usati per trovare date min o max, ma non è quello che l'OP sta cercando. Inoltre, la considerazione di una libreria di utilità è un argomento ostinato.
detj

13
Rispettosamente non sono d'accordo e penso che questa sia una risposta utile, @detj - la domanda dell'OP come formulata attualmente presume che ci sia una funzione incorporata o che debba scrivere la sua, ma questo non è vero. Mi sembra ragionevole indicare le librerie di utilità come alternativa a una delle soluzioni proposte dall'OP. Ma il tuo ragionamento è difendibile e il tuo voto è il tuo.
Mark Amery

16

Come applica, ora con diffusione :

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

(potrebbe essere un commento sulla migliore risposta)


12

Poiché le date vengono convertite in UNIX epoch (numeri), puoi utilizzare Math.max / min per trovare quelle:

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

(testato solo in Chrome, ma dovrebbe funzionare nella maggior parte dei browser)


8

** Usa gli operatori di diffusione | 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);

Ciò fornirà la data minima dall'array.

La sua abbreviazione Math.min.apply (null, ArrayOfdates);


1
In caso di voto negativo, commentare. Perché questa è una cattiva opzione? Mi piace la sintassi e per i piccoli array, la penalizzazione delle prestazioni è trascurabile.
GijsjanB

1
Sono stato downvoted. La risposta di Rudresh è un duplicato della mia sopra. Non ho idea del motivo per cui alla gente non piace questo. È una singola riga di codice contro molte righe.

3
Questo restituisce un numero non una data, quindi devi riconvertirlo in una data. Ma è piuttosto elegante altrimenti.
Tomáš Hübelbauer

6

ONELINER :

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

risultato in variabili mine max, complessità O (nlogn) , esempio modificabile qui . Se il tuo array ha valori senza data (come null), puliscilo prima con dates=dates.filter(d=> d instanceof Date);.


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

1

Le risposte sopra non gestiscono valori vuoti / non definiti per risolvere questo problema Ho usato il codice seguente e ho sostituito gli spazi vuoti con 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));

Ho aggiunto qui una semplice demo javascript e l'ho usata come filtro con AngularJS in questo codepen



-2

Utilizzando Moment , Underscore e jQuery , per iterare un array di date.

JSON di esempio:

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

Spero che sia d'aiuto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.