JavaScript-Datumsobjektvergleich

86

Beim Vergleichen von Datumsobjekten in Javascript stellte ich fest, dass selbst ein Vergleich desselben Datums nicht true zurückgibt.

 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

Wie kann ich die Gleichheit dieser Daten vergleichen? Ich bin daran interessiert, das native DateObjekt von JS und keine Bibliotheken von Drittanbietern zu verwenden, da es nicht angemessen ist, JS von Drittanbietern nur zum Vergleichen der Daten zu verwenden.

Harshana
quelle
15
Hervorragendes Beispiel dafür, wie schlecht dies in JavaScript gestaltet ist.
Devios1

Antworten:

130

Dies liegt daran, dass im zweiten Fall die tatsächlichen Datumsobjekte verglichen werden und zwei Objekte niemals gleich sind. Zwinge sie zur Nummerierung:

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

Wenn Sie eine explizitere Konvertierung in eine Zahl wünschen, verwenden Sie entweder:

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

oder

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

Oh, ein Verweis auf die Spezifikation: §11.9.3 Der abstrakte Gleichheitsvergleichsalgorithmus , der beim Vergleichen von Objekten grundsätzlich besagt, obj1 == obj2ist nur dann wahr, wenn sie sich auf dasselbe Objekt beziehen, andernfalls ist das Ergebnis falsch.

RobG
quelle
5
@ AndrewD. Die Verwendung von strengen Gleichungen in diesem speziellen Fall hat keinen Einfluss auf die Ergebnisse. Dies liegt daran, dass der Gleichheitsoperator in den Beispielen immer mit Operanden desselben Typs arbeitet. @RobG konvertiert die Werte explizit in Zahl (Beispiel 1 und 3) oder in Beispiel 2 wissen wir, dass Date.prototype.getTimeimmer eine Zahl zurückgegeben wird ...
Christian C. Salvadó
12
Zu Ihrer
Information
2
@ Nick - selbst die langsamste Version benötigt weniger als eine Mikrosekunde, sodass bei vergleichenden Unterschieden der Leistungsunterschied in absoluten Zahlen vernachlässigbar ist. Das OP sollte nur den Ansatz auswählen, der am besten geeignet getTimeist. Wahrscheinlich ist die Verwendung aus Gründen der Übersichtlichkeit am besten (und in den von mir getesteten Browsern am schnellsten).
RobG
2
@RobG Du weißt, du hast absolut recht. =) Ich habe eine Bibliothek geschrieben und einen Test "nur weil" gemacht. In echter Software macht es überhaupt keinen Unterschied.
Nick Zalutskiy
24

Vergleichen Sie die Daten anhand getTime()der Anzahl der Millisekunden aus der Epoche (dh einer Zahl):

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

Ziehen Sie auch in Betracht, einen DateKonstruktor zu verwenden, der eine explizite Jahres- / Monats- / Datumsnummer verwendet, anstatt sich auf die Zeichenfolgendarstellung zu verlassen (siehe: Date.parse () ). Und denken Sie daran, dass Daten in JavaScript immer in der Zeitzone des Clients (Browsers) dargestellt werden.

Tomasz Nurkiewicz
quelle
1
+1 für den Kommentar zur Verwendung von Zeichenfolgen als Argument für Date ().
RobG
16

Sie müssen die getTime-Methode nicht verwenden. Sie können ein Datumsobjekt von einem anderen Datumsobjekt subtrahieren. Die Millisekunden-Differenz wird zurückgegeben (negativ, wenn die Sekunde ein späteres Datum ist).

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

var diff= (startDate1 -startDate2)

// wird mit 0 ausgewertet, wenn die Daten denselben Zeitstempel haben

kennebec
quelle
+1 einfache und elegante, imo bevorzugte Lösung: Dies verwendet die integrierte
Datumsauswertungsfunktion,
5

Sie können die tatsächlichen Millisekunden vergleichen:

alert(startDate2.getTime() === startDate3.getTime());
gion_13
quelle
0

Sie können auch die Funktion valueOf () verwenden

 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
PeteBaser
quelle