Comparaison des objets de date JavaScript

86

En comparant des objets de date en Javascript, j'ai trouvé que même la comparaison de la même date ne retournait pas vrai.

 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

Comment comparer l'égalité de ces dates? Je suis intéressé par l'utilisation de l' Dateobjet natif de JS et non par des bibliothèques tierces car il n'est pas approprié d'utiliser un JS tiers juste pour comparer les dates.

Harshana
la source
15
Excellent exemple de la façon dont cela est mal conçu en JavaScript.
devios1

Réponses:

131

En effet, dans le second cas, les objets de date réels sont comparés et deux objets ne sont jamais égaux l'un à l'autre. Obligez-les à numéroter:

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

Si vous souhaitez une conversion plus explicite en nombre, utilisez soit:

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

ou

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

Oh, une référence à la spécification: §11.9.3 L'algorithme de comparaison d'égalité abstraite qui dit fondamentalement lors de la comparaison d'objets, obj1 == obj2n'est vrai que s'ils se réfèrent au même objet, sinon le résultat est faux.

RobG
la source
5
@AndrewD. l'utilisation d'égaux stricts dans ce cas particulier ne fait aucune différence sur les résultats, c'est parce que l'opérateur égal dans les exemples, traite toujours des opérandes du même type, @RobG convertit les valeurs explicitement en nombre (exemple 1 et 3) ou dans l'exemple 2, nous savons que Date.prototype.getTimeretournera toujours un nombre ...
Christian C. Salvadó
12
Pour info, il existe une différence de performance significative entre ces approches: jsperf.com/date-equality-comparison
Nick Zalutskiy
2
@ Nick - même la version la plus lente prend moins d'une microseconde à s'exécuter, donc s'il existe des différences comparatives, en termes absolus, la différence de performances est négligeable. L'OP devrait simplement choisir l'approche qui convient le mieux, l'utilisation getTimeest probablement la meilleure pour la clarté (et se trouve être la plus rapide dans les navigateurs que j'ai testés).
RobG
2
@RobG Vous savez, vous avez absolument raison. =) J'écrivais une bibliothèque et j'ai fait un test "juste cuz." Dans les vrais logiciels, cela ne fait aucune différence.
Nick Zalutskiy
24

Comparez les dates en utilisant le getTime()nombre de millisecondes renvoyé à l'époque (c'est-à-dire un nombre):

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

Pensez également à utiliser un Dateconstructeur prenant un nombre explicite d'année / mois / date plutôt que de vous fier à une représentation sous forme de chaîne (voir: Date.parse () ). Et rappelez-vous que les dates en JavaScript sont toujours représentées à l'aide du fuseau horaire du client (navigateur).

Tomasz Nurkiewicz
la source
1
+1 pour le commentaire sur l'utilisation de chaînes comme argument de Date ().
RobG
16

Vous n'avez pas besoin d'utiliser la méthode getTime - vous pouvez soustraire un objet date d'un autre objet date. Il renverra la différence en millisecondes (négative, si la seconde est une date ultérieure)

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

var diff= (startDate1 -startDate2)

// évalue à 0 si les dates ont le même horodatage

Kennebec
la source
+1 solution simple et élégante, préférée de l'OMI: cela utilise la fonctionnalité intégrée d'évaluation de la date sans avoir besoin de coercition sur un horodatage numérique
gdibble
5

vous pouvez comparer les millisecondes réelles:

alert(startDate2.getTime() === startDate3.getTime());
gion_13
la source
0

Vous pouvez également utiliser la fonction 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
PeteBaser
la source