การเปรียบเทียบวัตถุวันที่ JavaScript


87

เมื่อเปรียบเทียบออบเจ็กต์วันที่ใน Javascript ฉันพบว่าการเปรียบเทียบวันที่เดียวกันก็ไม่ได้เป็นจริง

 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

ฉันจะเปรียบเทียบความเท่าเทียมกันของวันที่เหล่านี้ได้อย่างไร ฉันสนใจที่จะใช้Dateออบเจ็กต์ดั้งเดิมของ JS และไม่ใช่ไลบรารีของบุคคลที่สามเนื่องจากไม่เหมาะสมที่จะใช้ JS ของบุคคลที่สามเพียงเพื่อเปรียบเทียบวันที่


16
ตัวอย่างที่ดีเยี่ยมว่าสิ่งนี้ออกแบบมาไม่ดีใน JavaScript อย่างไร
devios1

คำตอบ:


133

นั่นเป็นเพราะในกรณีที่สองจะมีการเปรียบเทียบวัตถุวันที่จริงและวัตถุสองชิ้นจะไม่เท่ากัน บีบบังคับให้หมายเลข:

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

หากคุณต้องการแปลงเป็นตัวเลขที่ชัดเจนมากขึ้นให้ใช้อย่างใดอย่างหนึ่ง:

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

หรือ

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

โอ้การอ้างอิงถึงข้อมูลจำเพาะ: §11.9.3 อัลกอริธึมการเปรียบเทียบความเท่าเทียมเชิงนามธรรมซึ่งโดยทั่วไปกล่าวว่าเมื่อเปรียบเทียบวัตถุobj1 == obj2จะเป็นจริงก็ต่อเมื่อพวกเขาอ้างถึงวัตถุเดียวกันมิฉะนั้นผลลัพธ์จะเป็นเท็จ


5
@AndrewD. การใช้การเท่ากับแบบเข้มงวดในกรณีนี้ไม่ได้สร้างความแตกต่างใด ๆ กับผลลัพธ์เนื่องจากตัวดำเนินการเท่ากับในตัวอย่างมักจะจัดการกับตัวถูกดำเนินการประเภทเดียวกันเสมอ @RobG กำลังแปลงค่าเป็นตัวเลขอย่างชัดเจน (ตัวอย่างที่ 1 และ 3) หรือในตัวอย่างที่ 2 เรารู้ว่าDate.prototype.getTimeจะส่งกลับตัวเลขเสมอ ...
Christian C. Salvadó

12
FYI มีความแตกต่างด้านประสิทธิภาพอย่างมีนัยสำคัญระหว่างแนวทางเหล่านี้: jsperf.com/date-equality-comparison
Nick Zalutskiy

2
@ Nick แม้เวอร์ชันที่ช้าที่สุดจะใช้เวลาน้อยกว่าไมโครวินาทีในการรันดังนั้นแม้ว่าจะมีความแตกต่างในเชิงเปรียบเทียบ แต่ความแตกต่างของประสิทธิภาพก็ไม่สำคัญ OP ควรเลือกวิธีใดก็ตามที่เหมาะสมที่สุดน่าจะใช้getTimeดีที่สุดเพื่อความชัดเจน (และเร็วที่สุดในเบราว์เซอร์ที่ฉันทดสอบด้วย)
RobG

2
@RobG คุณรู้ว่าคุณพูดถูกจริงๆ =) ฉันกำลังเขียนห้องสมุดและทำการทดสอบ "เพียงเพราะ" ในซอฟต์แวร์จริงจะไม่สร้างความแตกต่าง แต่อย่างใด
Nick Zalutskiy

1
@ Johannes— ดูunary + ใช้ทำอะไรใน Javascript และผู้ประกอบการ + เอก
RobG

24

เปรียบเทียบวันที่โดยใช้getTime()จำนวนมิลลิวินาทีที่กลับมาจากยุค (เช่นตัวเลข):

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

นอกจากนี้ให้พิจารณาใช้ตัวDateสร้างโดยใช้หมายเลขปี / เดือน / วันที่ที่ชัดเจนแทนที่จะใช้การแสดงสตริง (ดู: Date.parse () ) และจำไว้ว่าวันที่ใน JavaScript จะแสดงโดยใช้เขตเวลาไคลเอนต์ (เบราว์เซอร์) เสมอ


1
+1 สำหรับความคิดเห็นเกี่ยวกับการใช้สตริงเป็นอาร์กิวเมนต์ของ Date ()
RobG

16

คุณไม่จำเป็นต้องใช้เมธอด getTime - คุณสามารถลบวัตถุวันที่ออกจากวัตถุวันที่อื่นได้ มันจะคืนค่าความแตกต่างของมิลลิวินาที (ค่าลบถ้าวินาทีนั้นเป็นวันที่ในภายหลัง)

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

var diff= (startDate1 -startDate2)

// ประเมินเป็น 0 หากวันที่มีการประทับเวลาเดียวกัน


+1 วิธีการแก้ปัญหาที่เรียบง่ายและสง่างามที่ต้องการของ imo: ใช้ฟังก์ชันการประเมินวันที่ในตัวโดยไม่ต้องบังคับให้ประทับเวลาตัวเลข
gdibble

5

คุณสามารถเปรียบเทียบมิลลิวินาทีจริง:

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

0

คุณยังสามารถใช้ฟังก์ชัน 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.