Perbandingan Objek Tanggal JavaScript

87

Saat membandingkan objek tanggal di Javascript saya menemukan bahwa bahkan membandingkan tanggal yang sama tidak mengembalikan 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

Bagaimana saya bisa membandingkan kesetaraan tanggal-tanggal ini? Saya tertarik untuk menggunakan Dateobjek asli JS dan bukan pustaka pihak ketiga karena tidak tepat menggunakan JS pihak ketiga hanya untuk membandingkan tanggal.

Harshana
sumber
16
Contoh bagus tentang bagaimana ini dirancang dengan buruk di JavaScript.
devios1

Jawaban:

133

Itu karena dalam kasus kedua, objek tanggal sebenarnya dibandingkan, dan dua objek tidak pernah sama satu sama lain. Paksa mereka untuk menghitung:

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

Jika Anda menginginkan konversi yang lebih jelas ke angka, gunakan salah satu:

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

atau

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

Oh, referensi ke spek: §11.9.3 Algoritma Perbandingan Persamaan Abstrak yang pada dasarnya mengatakan ketika membandingkan objek, obj1 == obj2adalah benar hanya jika mereka merujuk ke objek yang sama, jika tidak hasilnya salah.

RobG
sumber
5
@Distroartonline. menggunakan sama ketat dalam kasus khusus ini tidak membuat perbedaan apa pun pada hasil, ini karena operator sama dengan dalam contoh, selalu berurusan dengan operan dari jenis yang sama, @RobG mengubah nilai secara eksplisit ke Angka (contoh 1 dan 3) atau dalam contoh 2, kita tahu bahwa Date.prototype.getTimeakan selalu mengembalikan Angka ...
Christian C. Salvadó
12
FYI, ada perbedaan kinerja yang signifikan antara pendekatan ini: jsperf.com/date-equality-comparison
Nick Zalutskiy
2
@ Nick — bahkan versi paling lambat membutuhkan waktu kurang dari satu mikrodetik untuk dijalankan, jadi meskipun ada perbedaan komparatif, secara absolut perbedaan performa dapat diabaikan. OP seharusnya hanya memilih pendekatan mana yang paling sesuai, kemungkinan penggunaan getTimepaling baik untuk kejelasan (dan kebetulan tercepat di browser yang saya uji juga).
RobG
2
@RobG Anda tahu, Anda benar sekali. =) Saya sedang menulis perpustakaan dan melakukan tes "hanya karena." Dalam perangkat lunak nyata, tidak ada bedanya sama sekali.
Nick Zalutskiy
1
@ Johannes — lihat Untuk apa unary + digunakan dalam Javascript? dan Operator unary + .
RobG
24

Bandingkan tanggal menggunakan getTime()kembali milidetik dari periode (yaitu angka):

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

Juga pertimbangkan untuk menggunakan Datekonstruktor yang mengambil nomor tahun / bulan / tanggal eksplisit daripada mengandalkan representasi string (lihat: Date.parse () ). Dan ingatlah bahwa tanggal dalam JavaScript selalu direpresentasikan menggunakan zona waktu klien (browser).

Tomasz Nurkiewicz
sumber
1
+1 untuk komentar tentang penggunaan string sebagai argumen untuk Date ().
RobG
16

Anda tidak perlu menggunakan metode getTime - Anda dapat mengurangi objek tanggal dari objek tanggal lain. Ini akan mengembalikan perbedaan milidetik (negatif, jika detik kemudian tanggal)

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

var diff= (startDate1 -startDate2)

// mengevaluasi ke 0 jika tanggal memiliki stempel waktu yang sama

kennebec
sumber
+1 sederhana dan elegan, solusi yang saya sukai: ini menggunakan fungsionalitas evaluasi Tanggal
bawaan
5

Anda dapat membandingkan milidetik sebenarnya:

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

Anda juga dapat menggunakan fungsi 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
sumber