JavaScript 中的日期比较:优化与性能

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

JavaScript 中的日期比较:如何避免踩坑并加速代码

\n\n

想象一下:你正在编写一个在线商店,需要检查商品折扣是否已过期。或者你在制作一个任务日历,需要筛选出今天的活动。又或者你在收集分析数据——"显示过去一周的所有订单"。在这些场景中,你都需要比较两个日期。看起来很简单,对吧?但 JavaScript 一如既往地准备给你带来惊喜。

\n\n

Stack Overflow 上关于 "Compare two dates with JavaScript" 的问题获得了数千次浏览——这并非偶然。即使是经验丰富的开发者,也常常在处理日期时遇到一些不明显的特性而犯错。在本文中,我们不仅会展示如何比较两个日期,还会分析哪种方法更快、哪种更安全。开始吧!

\n\n

为什么简单的日期比较行不通?

\n\n

我们先从新手常犯的经典错误开始。假设我们有两个日期:

\n\n
let date1 = new Date('2024-03-15');\nlet date2 = new Date('2024-03-20');\n\nconsole.log(date1 < date2);  // true\nconsole.log(date1 > date2);  // false\nconsole.log(date1 == date2); // false\n
\n\n

使用 < 和 > 运算符时一切正常。JavaScript 会将 Date 对象转换为数字(毫秒)并进行比较。但 == 运算符(以及严格等于 ===)的行为则不同。它比较的是对象的引用,而不是它们的值。两个不同的日期就是两个不同的对象,因此 == 总是返回 false,即使这两个日期精确到毫秒也完全相同。

\n\n

这是第一个陷阱。由此得出的教训是:永远不要使用 == 或 === 来比较日期。只能使用 <、>、<=、>= 或专门的方法。

\n\n

getTime() 方法:日期比较的黄金标准

\n\n

最可靠且性能最高的方法是使用 getTime()。它返回自 1970 年 1 月 1 日(Unix 纪元)以来经过的毫秒数。而 JavaScript 非常擅长比较数字:

\n\n
let date1 = new Date('2024-03-15T10:00:00');\nlet date2 = new Date('2024-03-15T10:00:00');\nlet date3 = new Date('2024-03-20T10:00:00');\n\nconsole.log(date1.getTime() === date2.getTime()); // true\nconsole.log(date1.getTime() < date3.getTime());   // true\nconsole.log(date1.getTime() > date3.getTime());   // false\n
\n\n

为什么这很高效?因为 getTime() 是一个非常轻量级的操作。它只是返回 Date 对象内部已经存储的数值。无需解析,无需额外计算。仅仅是一个数字。

\n\n

让我们来测量一下性能。以下是在浏览器控制台中进行的一个小测试:

\n\n
let date1 = new Date('2024-01-01');\nlet date2 = new Date('2024-12-31');\n\nconsole.time('getTime');\nfor (let i = 0; i < 1000000; i++) {\n    date1.getTime() < date2.getTime();\n}\nconsole.timeEnd('getTime');\n// 结果:在现代浏览器中约 5-10 毫秒\n
\n\n

一百万次比较在 10 毫秒内完成——这是一个非常棒的结果。相比之下,其他方法可能会慢 2-3 倍。

\n\n

使用 valueOf() 比较日期

\n\n

valueOf() 方法做的事情与 getTime() 相同——返回日期的数值表示。但有一个细微差别:当使用比较运算符(<、> 等)时,JavaScript 会隐式调用 Date 对象的 valueOf()。也就是说,下面这段代码:

\n\n
let date1 = new Date('2024-03-15');\nlet date2 = new Date('2024-03-20');\nconsole.log(date1 < date2);\n
\n\n

实际上是这样工作的:

\n\n
console.log(date1.valueOf() < date2.valueOf());\n
\n\n

因此,对于简单的 < 和 > 比较,可以直接使用 Date 对象。但对于精确的相等性比较(===),这行不通,这时就需要使用 getTime() 或 va

博客

书籍推荐