So sánh đối tượng ngày trong JavaScript


86

Khi so sánh các đối tượng ngày tháng trong Javascript, tôi thấy rằng ngay cả khi so sánh cùng một ngày tháng cũng không trả về 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

Làm thế nào tôi có thể so sánh sự bình đẳng của những ngày này? Tôi quan tâm đến việc sử dụng Dateđối tượng gốc của JS chứ không phải bất kỳ thư viện nào của bên thứ ba vì không thích hợp để sử dụng JS của bên thứ ba chỉ để so sánh ngày tháng.


15
Ví dụ tuyệt vời về cách nó được thiết kế kém trong JavaScript.
lệch

Câu trả lời:


131

Đó là bởi vì trong trường hợp thứ hai, các đối tượng ngày tháng thực tế được so sánh và hai đối tượng không bao giờ bằng nhau. Bắt họ đánh số:

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

Nếu bạn muốn chuyển đổi thành số rõ ràng hơn, hãy sử dụng:

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

hoặc là

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

Ồ, tham chiếu đến đặc tả: §11.9.3 Thuật toán so sánh bình đẳng trừu tượng nói về cơ bản khi so sánh các đối tượng, obj1 == obj2chỉ đúng nếu chúng tham chiếu đến cùng một đối tượng, nếu không kết quả là sai.


5
@AndrewD. việc sử dụng các dấu bằng nghiêm ngặt trong trường hợp cụ thể này không tạo ra sự khác biệt nào về kết quả, điều này là do toán tử bằng trong các ví dụ, luôn xử lý các toán hạng cùng loại, @RobG đang chuyển đổi các giá trị một cách rõ ràng thành Số (ví dụ 1 và 3) hoặc trong ví dụ 2, chúng ta biết rằng Date.prototype.getTimesẽ luôn luôn trả về một số ...
Christian C. Salvadó

12
FYI, có một sự khác biệt hiệu suất đáng kể giữa các phương pháp: jsperf.com/date-equality-comparison
Nick Zalutskiy

2
@ Nick — ngay cả phiên bản chậm nhất cũng mất ít hơn một micro giây để chạy, vì vậy mặc dù có sự khác biệt so sánh, nhưng về mặt tuyệt đối, sự khác biệt về hiệu suất là không đáng kể. OP chỉ nên chọn bất kỳ cách tiếp cận nào phù hợp nhất, có khả năng sử dụng getTimelà tốt nhất để rõ ràng (và xảy ra là nhanh nhất trong các trình duyệt tôi đã thử nghiệm).
RobG

2
@RobG Bạn biết đấy, bạn hoàn toàn đúng. =) Tôi đang viết thư viện và đã làm một bài kiểm tra "just cuz." Trong phần mềm thực, nó không có gì khác biệt.
Nick Zalutskiy


24

So sánh ngày bằng cách sử dụng getTime()số mili giây trả về từ kỷ nguyên (tức là một số):

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

Cũng nên xem xét sử dụng hàm Datetạo lấy số năm / tháng / ngày rõ ràng thay vì dựa vào biểu diễn chuỗi (xem: Date.parse () ). Và hãy nhớ rằng ngày trong JavaScript luôn được thể hiện bằng múi giờ của máy khách (trình duyệt).


1
+1 cho nhận xét về việc sử dụng chuỗi làm đối số cho Date ().
RobG

16

Bạn không cần sử dụng phương thức getTime- bạn có thể trừ một đối tượng ngày tháng khỏi một đối tượng ngày tháng khác. Nó sẽ trả về chênh lệch mili giây (âm, nếu giây là một ngày muộn hơn)

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

var diff= (startDate1 -startDate2)

// đánh giá là 0 nếu các ngày có cùng dấu thời gian


1 đơn giản và thanh lịch, giải pháp imo ưa thích: sử dụng này tích hợp chức năng thẩm định ngày mà không cần phải ép buộc vào một số dấu thời gian
gdibble

5

bạn có thể so sánh mili giây thực tế:

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

0

Bạn cũng có thể sử dụng hàm 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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.