Confronto tra oggetti data JavaScript


87

Quando si confrontano gli oggetti data in Javascript, ho scoperto che anche il confronto della stessa data non restituisce true.

 var startDate1 = new Date("02/10/2012");
 var startDate2 = new Date("01/10/2012");
 var startDate3 = new Date("01/10/2012");
 alert(startDate1>startDate2); // true
 alert(startDate2==startDate3); //false

Come posso confrontare l'uguaglianza di queste date? Sono interessato a utilizzare l' Dateoggetto nativo di JS e non le librerie di terze parti poiché non è appropriato utilizzare un JS di terze parti solo per confrontare le date.


16
Ottimo esempio di come questo sia mal progettato in JavaScript.
devios1

Risposte:


133

Questo perché nel secondo caso vengono confrontati gli oggetti della data effettiva e due oggetti non sono mai uguali tra loro. Costringili a numerare:

 alert( +startDate2 == +startDate3 ); // true

Se desideri una conversione più esplicita in numero, utilizza uno dei seguenti:

 alert( startDate2.getTime() == startDate3.getTime() ); // true

o

 alert( Number(startDate2) == Number(startDate3) ); // true

Oh, un riferimento alla specifica: §11.9.3 L'algoritmo di confronto dell'uguaglianza astratta che fondamentalmente dice quando si confrontano oggetti, obj1 == obj2è vero solo se si riferiscono allo stesso oggetto, altrimenti il ​​risultato è falso.


5
@AndrewD. l'uso di uguali stretti in questo caso particolare non fa alcuna differenza sui risultati, questo perché l'operatore uguale negli esempi, ha sempre a che fare con operandi dello stesso tipo, @RobG converte i valori esplicitamente in Numero (esempio 1 e 3) o nell'esempio 2, sappiamo che Date.prototype.getTimerestituirà sempre un numero ...
Christian C. Salvadó

12
Cordiali saluti, c'è una differenza di prestazioni significativa tra questi approcci: jsperf.com/date-equality-comparison
Nick Zalutskiy

2
@ Nick — anche la versione più lenta impiega meno di un microsecondo per essere eseguita, quindi, sebbene ci siano differenze comparative, in termini assoluti la differenza di prestazioni è trascurabile. L'OP dovrebbe semplicemente scegliere quale approccio si adatta meglio, probabilmente l'uso getTimeè il migliore per chiarezza (e sembra essere il più veloce anche nei browser che ho testato).
RobG

2
@ RobG Sai, hai assolutamente ragione. =) Stavo scrivendo una libreria e ho fatto un test "just cuz." Nel software reale non fa alcuna differenza.
Nick Zalutskiy


24

Confronta le date utilizzando il getTime()numero di millisecondi di ritorno dall'epoca (ad esempio un numero):

var startDate1 = new Date("02/10/2012");
var startDate2 = new Date("01/10/2012");
var startDate3 = new Date("01/10/2012");
alert(startDate1.getTime() > startDate2.getTime()); // true
alert(startDate2.getTime() == startDate3.getTime()); //true

Considera anche l'utilizzo del Datecostruttore che prende un numero esplicito di anno / mese / data piuttosto che fare affidamento sulla rappresentazione di stringa (vedi: Date.parse () ). E ricorda che le date in JavaScript sono sempre rappresentate utilizzando il fuso orario del client (browser).


1
+1 per il commento sull'uso delle stringhe come argomento di Date ().
RobG

16

Non è necessario utilizzare il metodo getTime: è possibile sottrarre un oggetto data da un altro oggetto data. Restituirà la differenza dei millisecondi (negativa, se il secondo è una data successiva)

var startDate1 = new Date("02/10/2012");
var startDate2 = new Date("01/10/2012");

var diff= (startDate1 -startDate2)

// restituisce 0 se le date hanno lo stesso timestamp


+1 soluzione semplice ed elegante, preferita da imo: utilizza la funzionalità di valutazione della data incorporata senza la necessità di coercizione per un timestamp numerico
gdibble

5

puoi confrontare i millisecondi effettivi:

alert(startDate2.getTime() === startDate3.getTime());

0

Puoi anche usare la funzione valueOf ()

 var startDate1 = new Date("02/10/2012").valueOf();
 var startDate2 = new Date("01/10/2012").valueOf();
 var startDate3 = new Date("01/10/2012").valueOf();
 alert(startDate1>startDate2); // 1326150000000 > 1328828400000   true
 alert(startDate2==startDate3); // 1328828400000 > 1326150000000  false
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.