
文档教程知识库【免费下载链接】til:memo: Today I Learned项目地址https://gitcode.com/gh_mirrors/ti/til点击查看免费下载在 JavaScript 里判断两个Date对象是否相等并不是一个直观的操作——即使两个对象在概念上甚至打印出来完全相同直接使用比较也往往得到false。本篇技术指南以 TIL 仓库中的 compare-the-equality-of-two-date-objects.md 为主体讲解为什么对象比较会失灵、如何借助getTime()把日期转换为数字来完成可靠判断以及、、、运算符为何可以直接用于日期比较并延伸介绍与之配套的日期解析、时区与毫秒/秒陷阱。为什么两个一样的 Date 对象不相等JavaScript 中的相等性判断对对象有一套与基本类型完全不同的规则。对于基本类型数字、字符串等比较的是值而对于对象包括Date实例比较的是引用——即两个变量是否指向内存中的同一个对象。所以即使两个Date对象内部携带完全相同的时刻只要它们是通过两次独立构造产生的就会被视为不相等。这是理解日期相等性比较的第一块基石const now Date.now(); const today1 new Date(now); const today2 new Date(now); today1 today2 // false —— 两个独立对象引用不同用 getTime() 将日期转换为数字再比较要判断两个Date对象是否代表同一时刻正确思路是先把它们转换成一个可以用值比较的东西——数字。Date.prototype.getTime()正是为此而生的它返回该日期相对于 Unix 纪元1970-01-01 00:00:00 UTC的毫秒数是一个纯数字天然适合相等性判断。 now Date.now() today1 new Date(now) today2 new Date(now) today1 today2 false today1.getTime() today2.getTime() true由于getTime()返回的是 UTC 毫秒时间戳这种比较方式天然不受本地时区影响只要两个日期对象指向同一时刻无论当前机器时区如何它们的getTime()结果都完全一致。其他等价写法除了显式调用getTime()下面几种写法也能得到同样的数字化效果可在不同场景下选用// 一元加号运算符等价于调用 valueOf() date1 date2 // 显式调用 valueOf() date1.valueOf() date2.valueOf() // 对象转数字的隐式触发 Number(date1) Number(date2)Date对象的valueOf()与getTime()语义相同都返回毫秒时间戳。需要提醒的是这类写法在代码可读性上不如getTime()直白团队协作时优先推荐显式写法。比较大小Date 对象可以直接使用 、、、与相等性判断不同Date对象可以直接使用关系运算符、、、来比较先后顺序const earlier new Date(2024-01-01T00:00:00Z); const later new Date(2024-06-01T00:00:00Z); later earlier // true earlier later // true earlier later // true later earlier // true原因在于关系运算符在遇到对象时会先通过内部的ToPrimitive转换把对象强制转换为原始值对Date而言优先得到数字毫秒时间戳然后再按数字大小进行比较。因此later earlier实际等价于later.getTime() earlier.getTime()比较的是时间戳数值结果可靠且符合直觉。区分两种情况相等用 getTime()大小直接用运算符把两种场景放在一起对比结论非常清晰比较目标推荐写法说明是否相等同一时刻a.getTime() b.getTime()比较引用必须先转为数字是否相等宽松a b不推荐依赖隐式转换可读性差容易误用先后/大小a b、a b、a b、a b运算符自动完成 ToPrimitive 转换可直接使用务必警惕a b这类宽松相等写法虽然Date对象在下会触发隐式转换从而碰巧能工作但这种写法语义晦涩也容易在与其他类型的值混用时产生意外结果实际项目中应避免。封装一个可复用的日期相等性函数为了把先转数字再比较的细节隔离在单个入口可以封装一个小工具函数方便在项目各处复用function isSameDate(a, b) { if (!(a instanceof Date) || !(b instanceof Date)) { throw new TypeError(isSameDate expects Date instances); } return a.getTime() b.getTime(); } isSameDate(new Date(2024-01-01T00:00:00Z), new Date(2024-01-01T00:00:00Z)) // trueinstanceof Date的类型检查可以避免传入null、字符串等非日期值导致难以排查的NaN NaN恒为false问题。延伸日期比较前必须绕开的三个陷阱围绕比较两个日期这一主题TIL 仓库中还记录了若干直接影响比较结果的关键细节比较前务必核对1. 字符串日期可能被按 UTC 解释ISO-8601 陷阱用字符串构造Date时解析规则并不统一。仓库中的 iso-8601-formatted-dates-are-interpreted-as-utc.md 记录了这样一个事实非 ISO-8601 格式如2017-12-4按本地时区解释而符合 ISO-8601 的格式如2017-12-04按UTC解释二者可能相差数小时、甚至跨天。因此在用字符串构造日期后再做比较时要明确输入格式的时区语义。2. 秒与毫秒传入整数时差了一千倍仓库中的 parse-a-date-from-a-timestamp.md 和 convert-seconds-to-date-object.md 都强调new Date(1618499080)期望的是毫秒时间戳而很多后端 API 返回的是秒。直接传入秒级时间戳会得到一个接近 1970 年的怪异日期比较结果自然完全错误。正确做法是乘以1000new Date(1713350171 * 1000) // 2024-04-17T10:36:11.000Z相应地Date.now()和getTime()返回的也都是毫秒注意保持单位一致。3. 时间分量与日期运算的辅助函数仓库中的 get-the-time-components-of-a-date.md 整理了getHours()、getMinutes()、getSeconds()、getMilliseconds()、getTimezoneOffset()等时间分量 APIcreate-future-and-past-dates-from-today.md 则演示了用setDate()/setFullYear()做日期加减运算。这些 API 常用于在比较前后对日期做归一化处理例如把时间部分清零后再判断是否同一天。替代方案用 DayJS 等库简化比较如果项目已经引入日期库可以借助其封装好的比较方法省去手动转换。仓库中的 easy-date-comparison-with-dayjs.md 记录了用 DayJS 判断日期是否已过期的做法import dayjs from dayjs; const today dayjs(new Date()); const pastDate dayjs(2018-10-22); const futureDate dayjs(2022-01-01); console.log(pastDate.isBefore(today)); // true console.log(futureDate.isBefore(today)); // falsedayjs()可以从Date对象或字符串构造 DayJS 实例再用isBefore()、isAfter()等函数直接比较。不过对于两个日期是否相等这种简单需求原生getTime()已经足够是否引入依赖可按项目实际情况权衡。小结两个独立构造的Date对象永远不能用判断相等因为对象比较的是引用判断是否代表同一时刻请用a.getTime() b.getTime()判断谁先谁后可以直接使用、、、运算符会自动把日期转换为数值时间戳比较之前注意字符串解析的时区规则、秒/毫秒单位差异等陷阱必要时参考 get-the-time-components-of-a-date.md、iso-8601-formatted-dates-are-interpreted-as-utc.md 与 convert-seconds-to-date-object.md 等笔记。更多相关实践可继续阅读 TIL 仓库的 JavaScript 目录 下的日期主题笔记例如 basic-date-formatting-without-a-library.md用Intl.DateTimeFormat做格式化与 easy-date-comparison-with-dayjs.mdDayJS 比较。赞分享文档教程知识库【免费下载链接】til:memo: Today I Learned项目地址https://gitcode.com/gh_mirrors/ti/til点击查看免费下载相关推荐30 Seconds of CodeJavaScript 中两个 Date 对象的比较相等、先后与区间判断完整指南30 Seconds of CodeJavaScript 中两个 Date 对象的比较相等、先后与区间判断完整指南 JavaScript 的 Date 对教程文档Mengzi-T5-Base性能评测在8大中文NLP任务中的表现分析Mengzi T5 Base性能评测在8大中文NLP任务中的表现分析 Mengzi T5 Base是一款针对中文优化的T5系列预训练模型在文本生成、翻译、摘Bun深度比较对象相等性判断的精准方法Bun深度比较对象相等性判断的精准方法 引言为什么需要深度比较 在日常JavaScript开发中对象比较是一个常见但容易出错的操作。传统的 操作语言运行时后端开发工具包管理器前端构建测试上一篇Grip部署实战指南5个步骤在生产环境中搭建终极Markdown预览服务下一篇Symfony CLI 工具使用教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考