写点什么

为什么 2025/05/28 和 2025-05-28 在 JavaScript 中是不同的日子?

brandondong

  • 2025-07-02
    北京
  • 本文字数:2348 字

    阅读完需:约 8 分钟

为什么2025/05/28和2025-05-28在JavaScript中是不同的日子?

译者 | 平川

策划 | Tina


在搭建这个网站的过程中,我遇到了以下奇怪的事情:


console.log(new Date('2025/05/28').toDateString()); // Wed May 28 2025console.log(new Date('2025-05-28').toDateString()); // Tue May 27 2025// 去掉月份的 0console.log(new Date('2025-5-28').toDateString()); // Wed May 28 2025
复制代码


你在你的机器上可能会得到不同的结果。


发生了什么?


在 JavaScript 中,Date代表一个时间点(即自纪元以来的毫秒数)。把完整的日期字符串打印出来就更明显了:


const date = new Date('2025/05/28');console.log(date); // Wed May 28 2025 00:00:00 GMT-0700 (Pacific Daylight Time)console.log(date.toDateString()); // Wed May 28 2025
复制代码


在这种情况下,传入的日期字符串被解释成我所在时区的一个时间戳。toDateString() 的操作也是相对于本地时间,所以我们得到了相同的月份日期。


和’2025-05-28’的区别在于解析行为。这个字符串被解释为 UTC,所以最终得到了不同的时间点:


const date = new Date('2025-05-28');console.log(date); // Tue May 27 2025 17:00:00 GMT-0700 (Pacific Daylight Time)console.log(date.toDateString()); // Tue May 27 2025
复制代码


为什么会有这种差异?


浏览器日期解析的冒险


在翻阅 Chrome/Firefox/Safari 的代码和提交历史后,我重建了一个时间线:


  • 2009 年,这些浏览器支持解析一系列日期 - 时间格式。当字符串中没有明确指定时区偏移时,它们都会转而使用本地时间,包括像’2025/05/28’这样的日期字符串。

  • ES5 在 2009 年年底发布,要求支持一种新的标准化日期 - 时间格式。在很大程度上,这种格式基于 ISO 8601。这种格式被分为仅日期形式(如’2025-05-28’)和日期 - 时间形式(如’2025-05-27T17:00-07:00’),其中末尾的 UTC 是可选的。

  • 对于没有偏移的仅日期形式或缺少偏移的日期 - 时间形式,关于时区解释,规范说了什么?只是说“字符串可能被解释为本地时间、UTC 时间或某个其他时区的时间,这取决于字符串的内容。”

  • Firefox 是第一个实现这一要求的。他们选择将仅日期形式解释为 UTC,将缺少偏移的日期 - 时间形式解释为本地时间。现在,不仅’2025/05/28’和’2025-05-28’之间存在差异,而且还有令人惊讶的行为,如下所示:


console.log(new Date('2025-05-28')); // Tue May 27 2025 17:00:00 GMT-0700 (Pacific Daylight Time)console.log(new Date('2025-05-28T00:00')); // Wed May 28 2025 00:00:00 GMT-0700 (Pacific Daylight Time)
复制代码


  • 接下来是 Chrome,选择对两者都使用本地时间。

  • 接下来是 Safari,但它的解析逻辑错误地要求必须提供日期、时间和偏移字段。

  • ES5.1 在 2011 年中发布,其中提到,缺少的时区偏移值为 Z。

  • Chrome 更新了其实现,对两种情况都使用 UTC。

  • Safari 修复了早期的 Bug,对两种情况都使用 UTC。

  • 有人提出了规范本身的一个 Bug,ISO 8601 将没有偏移的日期 - 时间表示为本地时间。2015 年,ES6 取代了 ES5.1,并补充道“如果不存在时区偏移,则将日期 - 时间解释为本地时间”。

  • Chrome 切换回对两种情况都使用本地时间。

  • 有人提出了 Chrome 的一个 Bug,它在解析仅日期形式时破坏了向后兼容性。他们撤销了之前的更改。

  • Chrome 提出了规范的一个 问题,经过讨论之后,仅日期形式切换回 UTC,但将缺少偏移的日期 - 时间形式仍为本地(即 Firefox 2009 年的行为)。

  • ES7 发布更新后的要求,Chrome 先做了更改,然后是 Safari。


这种行为一直维持到今天,除了像’2025-05-28’这样的有效 ISO 日期字符串之外,Date 构造函数会将接收到的每个可能的字符串都作为本地时间。


有趣的是,从 2009 年发布到 2020 年初,尽管被设计为标准格式,主要浏览器在处理缺少偏移的情况时从未一致过。与此同时,在解析’2025-05-28T00:00’时,Chrome 经历了多次反复(local → UTC → local → UTC → local )。而这一切只是为了解决 Firefox 2009 年的行为问题,在我看来,它是所有行为中最不直观的。


JavaScript Temporal


JavaScript Temporal 即将面世:这是一组新的日期和时间 API,旨在取代 Date 对象。


整个日期解析问题最初是源于时区歧义,但在很多情况下,我们希望将仅日期字符串视为纯日期。例如,当我说今年的圣诞节是 2025-12-25 时,我指的并不是 2025-12-25T00:00:00.000Z 这个时间。


Date 只能表示后者,而 Temporal 则提供了 纯日期(即不含时区的日期)选项。 '2025-12-25'就是 2025-12-25,完全避免了解析歧义的问题。


但如果我们真想把一个仅日期的字符串解析成一个时间戳呢?如果字符串本身没有时区,Temporal 会选择哪个时区?


答案是:这是一个严重错误;必须提供 偏移 或 时区标识符。不要重复犯错了。


被诅咒的区域


在阅读浏览器日期解析源代码之前,我从未意识到它可以如此宽容。


下面是 Chrome/Firefox 浏览器的一个有趣示例:你能找出为什么这个日期字符串被解析为五月吗?


const date = 'it is wednesday, my dudes. 2025, April, maybe...28(?)';console.log(new Date(date)); // Wed May 28 2025 00:00:00 GMT-0700 (Pacific Daylight Time)
复制代码


原文链接:


https://brandondong.github.io/blog/javascript_dates


声明:本文为 InfoQ 翻译,未经许可禁止转载。


今日好文推荐


用印度程序员冒充AI的“独角兽”彻底倒闭了!伪AI烧光5亿美元,连微软和亚马逊都被“坑”了


前端的下一轮演进:基于AI的状态管理


Next.js 真有那么好用吗?Netlify 谈他们遇到的六个现实问题


浏览器里的 AI 革命:前端工程师的新战场


活动推荐


6 月 27~28 日的 AICon 北京站将继续聚焦 AI 技术的前沿突破与产业落地,围绕 AI Agent 构建、多模态应用、大模型推理性能优化、数据智能实践、AI 产品创新等热门议题,深入探讨技术与应用融合的最新趋势。欢迎持续关注,和我们一起探索 AI 应用的无限可能!



2025-07-02 15:455920

评论

发布
暂无评论

Anthropic深夜推出王炸,全球首个混合推理模型诞生,编程能力吊打一切对手

Geek_99b519

人工智能 推理模型 openai cursor

Metasploit Framework 6.4.49 (macOS, Linux, Windows) - 开源渗透测试框架

sysin

Metasploit

H5 APP开发中的性能优化

北京木奇移动技术有限公司

软件外包公司 APP外包公司 APP开发公司

全国独家线下面授 | 北京·大规模敏捷LeSS认证5月9-11日开班

ShineScrum

LeSS认证 吕毅老师 CLP认证

爱回收获取询价项API接口(爱回收API系列)

tbapi

爱回收API 爱回收商品列表数据采集

25年重庆等保测评公司名称以及地址一览表

行云管家

等保 等保测评 重庆

Svelte 最新中文文档教程(19)—— 测试

冴羽

前端 前端开发 前端框架 Svelte SvelteKit

在华为开发者空间,调用DeepSeek实现代码自动生成

华为云开发者联盟

人工智能 大模型 DeepSeek 华为开发者空间 华为云主机

人工智能丨从零到一:如何构建一个智能化测试平台?

测试人

【堡垒机小知识】云堡垒机属于云安全产品吗?

行云管家

云计算 云安全 云堡垒机

看过来!Apache DolphinScheduler版本升级指南

白鲸开源

开源 技术 Apache DolphinScheduler 版本升级

「高盛」最新研报:人形机器人核心供应链上市企业投资分析(附报告)

机器人头条

投资 大模型 人形机器人 具身智能 宇树科技

ROI量化思路与智能制造的关系

积木链小链

数字化转型 制造业 智能制造

数字先锋 | 天翼云xDeepSeek,赋能东莞开启智慧政务新篇章!

天翼云开发者社区

人工智能 云服务 政务 大模型 DeepSeek

H5 APP开发的注意事项

北京木奇移动技术有限公司

APP开发 软件外包公司 APP外包公司

Metasploit Pro 4.22.7-2025022001 发布,新增功能概览

sysin

Metasploit

开发者低代码工具选型与部署指南

NocoBase

开源 低代码 零代码 开发工具 开发人员

全球预焙阳极龙头企业索通发展的数智化转型之路!

用友智能财务

AI 赋能指标管理分析,开启企业数智领航时代

袋鼠云数栈

AI 数字化转型 袋鼠云

全国独家线下面授 | 上海·大规模敏捷LeSS认证6月5-7日开班

ShineScrum

less 吕毅老师 CLP认证

H5 APP开发框架的对比

北京木奇移动技术有限公司

软件外包公司 APP外包 H5开发

智源开源FlagOS升级:首次实现DeepSeek-R1满血版多种芯片高效快速部署

智源研究院

为什么2025/05/28和2025-05-28在JavaScript中是不同的日子?_编程语言_InfoQ精选文章