JavaScript Tarih Nesne Karşılaştırması


87

Javascript'te tarih nesnelerini karşılaştırırken, aynı tarihi karşılaştırmanın bile doğru dönmediğini gördüm.

 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

Bu tarihlerin eşitliğini nasıl karşılaştırabilirim? DateYalnızca tarihleri ​​karşılaştırmak için bir üçüncü taraf JS kullanmak uygun olmadığından, herhangi bir üçüncü taraf kitaplığı değil, JS'nin yerel nesnesini kullanmakla ilgileniyorum .


16
Bunun JavaScript'te nasıl kötü tasarlandığına dair mükemmel bir örnek.
devios1

Yanıtlar:


133

Bunun nedeni, ikinci durumda, gerçek tarih nesnelerinin karşılaştırılması ve iki nesnenin asla birbirine eşit olmamasıdır. Onları numaraya zorlayın:

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

Sayıya daha açık bir dönüşüm istiyorsanız, aşağıdakilerden birini kullanın:

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

veya

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

Oh, spesifikasyona bir referans: §11.9.3 Temelde nesneleri karşılaştırırken söyleyen Soyut Eşitlik Karşılaştırma Algoritması , obj1 == obj2yalnızca aynı nesneye atıfta bulundukları takdirde doğrudur, aksi takdirde sonuç yanlıştır.


5
@AndrewD. Bu özel durumda katı eşittir kullanmak, sonuçlarda herhangi bir fark yaratmaz, bunun nedeni örneklerdeki eşittir operatörünün her zaman aynı türdeki işlenenlerle uğraşmasıdır, @RobG değerleri açıkça Sayıya dönüştürür (örnek 1 ve 3) veya 2. örnekte, bunun Date.prototype.getTimeher zaman bir Sayı döndüreceğini biliyoruz ...
Christian C. Salvadó

12
Bilginize, bu yaklaşımlar arasında önemli bir performans farkı var: jsperf.com/date-equality-comparison
Nick Zalutskiy

2
@ Nick - en yavaş sürümün bile çalışması bir mikrosaniyeden daha az sürer, bu nedenle karşılaştırmalı farklılıklar varken, mutlak terimlerle performans farkı ihmal edilebilir. OP, hangi yaklaşımı en uygunsa onu seçmelidir, muhtemelen kullanmak getTimenetlik için en iyisidir (ve test ettiğim tarayıcılarda da en hızlı olanıdır).
RobG

2
@RobG Biliyorsunuz, kesinlikle haklısınız. =) Bir kütüphane yazıyordum ve "sadece kuzen" bir test yaptım. Gerçek yazılımda hiçbir fark yaratmaz.
Nick Zalutskiy


24

Dönemden getTime()dönen milisaniye sayısını (yani bir sayı) kullanarak tarihleri ​​karşılaştırın :

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

Ayrıca Date, dize temsiline güvenmek yerine açık yıl / ay / tarih numarası alarak yapıcı kullanmayı düşünün (bkz: Date.parse () ). Ve JavaScript'teki tarihlerin her zaman istemci (tarayıcı) saat dilimi kullanılarak temsil edildiğini unutmayın.


1
Date () 'ye bağımsız değişken olarak dizeleri kullanma hakkındaki yorum için +1.
RobG

16

GetTime yöntemini kullanmanıza gerek yoktur - bir tarih nesnesini başka bir tarih nesnesinden çıkarabilirsiniz. Milisaniye farkını döndürür (ikincisi daha sonraki bir tarihse negatif)

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

var diff= (startDate1 -startDate2)

// tarihler aynı zaman damgasına sahipse 0 olarak değerlendirilir


+1 basit ve zarif, imo tercih edilen çözüm: bu, sayısal bir zaman damgasına zorlama gerektirmeden yerleşik Tarih değerlendirme işlevini kullanır
gdibble

5

gerçek milisaniyeleri karşılaştırabilirsiniz:

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

0

Ayrıca valueOf () işlevini de kullanabilirsiniz.

 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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.