网易首页 > 网易号 > 正文 申请入驻

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

0
分享至


在日常生活中,“2025/05/28” 和 “2025-05-28” 可能只是两种日期写法的区别——前者看起来更像美式格式,后者则更标准化一些。但在编程世界里,这种写法的不同,可能意味着完全不同的时间点。特别是在 JavaScript 中,这两者居然会被解析成不同的一天!

这种现象最近在 Hacker News 上引发了不少关注,不少开发者都表示曾在这类问题上“踩坑”甚至 debug 到深夜。一位网友就评论说:“我调了半天的日期 bug,最后才发现是字符串写法惹的祸。”还有人惊呼:“我们都以为是用户格式输错,结果是 JavaScript 的锅。”

对此,开发者 Brandon Dong 专门写了一篇《Why are 2025/05/28 and 2025-05-28 different days in JavaScript?》文章深入分析了背后的原因,不仅揭示了 Date 构造函数令人费解的行为,还带你回顾了一段浏览器与 ECMAScript 标准之间十多年来“反复横跳”的历史。接下来就让我们一起看看,JavaScript 为什么会把明明写着“2025 年 5 月 28 日”的两个字符串,解析成两个不一样的时间点。

原文链接:https://brandondong.github.io/blog/javascript_dates/

作者 | Brandon Dong

翻译 | 苏宓

出品 | CSDN(ID:CSDNnews)

在搭建个人网站的过程中,我遇到了一个奇怪的现象:

console.log(new Date('2025/05/28').toDateString()); // Wed May 28 2025
console.log(new Date('2025-05-28').toDateString()); // Tue May 27 2025
// Bonus: (omit leading 0)
console.log(new Date('2025-5-28').toDateString()); // Wed May 28 2025

你在自己电脑上运行时可能会得到不同的结果!


发生了什么?

在 JavaScript 中,一个 Date 对象始终表示一个时间点(即自 Unix 纪元以来的毫秒数)。这一点在输出完整时间字符串时更为明显:

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 标准提出了一种基于 ISO 8601 的新日期格式标准,包含一种纯日期形式:'2025-05-28',还有另一种日期+时间形式:'2025-05-27T17:00-07:00'(其中时区偏移可以省略)

    那么对于没有偏移信息的纯日期形式或省略偏移的日期时间形式,规范是怎么说的呢?答案是:字符串的时间可以被解释为本地时间、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
console.log(new Date('2025-05-28T00:00')); // Wed May 28 2025 00:00:00 GMT-0700

  • 接下来是 Chrome,它选择对这两种情况都使用本地时间。
  • 然后是 Safari,但其解析逻辑有 bug:要求必须提供日期、时间和偏移字段。

  • 2011 年年中发布的 ES5.1 进一步补充:如果缺少时区偏移,默认用 Z(即 UTC)。

  • Chrome 更新了其实现,对两种情况都按 UTC 时间解析。

  • Safari 修复 bug,也改为使用 UTC 时间。

  • 随后有人指出这种规范本身存在一个 bug:指出 ISO 8601 实际上规定“无偏移的日期时间”应被解释为本地时间。2015 年,ES6 将之前的说法替换为:如果省略时区偏移,日期时间应被解释为本地时间。

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

  • 之后又有人抱怨 Chrome 在解析纯日期格式时破坏了兼容性,Chrome 又改回 UTC。

  • Chrome 进一步向规范提交问题。经过讨论后,达成折中方案。

  • 纯日期形式→ UTC(Firefox 风格)

  • 缺偏移的日期时间形式→ 本地时间

  • ES7正式采用上述行为。Chrome 率先实现,随后 Safari 也跟进。

到今天为止,这个规则仍在沿用:只要传入的是合法的 ISO 日期字符串(如 '2025-05-28'),构造函数就会默认使用 UTC,否则一律用本地时间。

这种行为一直保持到今天,其中 Date 构造函数接受的每个可能的字符串都回退到本地时间,除了像 '2025-05-28' 这样的有效 ISO 日期字符串。

看这个时间线,有趣的是,尽管它被设计为标准化格式,但从 2009 年发布到 2020 年初,主要浏览器在缺少偏移量的情况下从未有过一致的行为。同时,Chrome 在解析 '2025-05-28T00:00' 时搞笑地从本地→UTC→本地→UTC→本地来回切换。而这一切只是为了最终采用 Firefox 2009 年的行为,在我看来,这是所有行为中最不直观的。


Temporal 呢?

对于不知道的人来说,JavaScript Temporal 即将到来:这是一组新的日期和时间 API,旨在取代 Date 对象。

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

虽然 Date 只能表示后者,但 Temporal 提供了纯日期(即没有时区的日期)的选项。'2025-12-25' 就只是 '2025-12-25',完全避开了解析歧义的问题。

但是,如果确实想将仅日期的字符串解析为一个时间点呢?当字符串本身缺少时区时,Temporal 会选择哪个时区?

答案是:根本不会让你这么干。

Temporal 在这方面是严格错误(hard error):必须明确提供时区偏移或时区标识符,否则它就直接抛错,根本不给你机会“犯老毛病”。

2025 全球产品经理大会

2025 年 8 月 15–16 日

北京·威斯汀酒店

2025 全球产品经理大会将汇聚互联网大厂、AI 创业公司、ToB/ToC 实战一线的产品人,围绕产品设计、用户体验、增长运营、智能落地等核心议题,展开 12 大专题分享,洞察趋势、拆解路径、对话未来。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
12秒98夺第1!吴艳妮预赛闪耀比心庆祝,跨栏女神对决,林雨薇第2

12秒98夺第1!吴艳妮预赛闪耀比心庆祝,跨栏女神对决,林雨薇第2

李喜林篮球绝杀
2025-11-19 10:28:03
弟弟结婚不让去,我关机旅行,开机后看到我妈打来300个未接来电

弟弟结婚不让去,我关机旅行,开机后看到我妈打来300个未接来电

木槿纪实
2025-11-19 09:29:29
阿里开始严查午休

阿里开始严查午休

蚂蚁大喇叭
2025-11-17 09:56:58
解决Siri这座“屎山”,是苹果新掌门的头号任务

解决Siri这座“屎山”,是苹果新掌门的头号任务

字母榜
2025-11-17 16:09:01
震惊!新型穷人症状曝光,网友称已“病入膏肓”!

震惊!新型穷人症状曝光,网友称已“病入膏肓”!

特约前排观众
2025-11-19 00:15:03
71岁成龙去世?最新消息!

71岁成龙去世?最新消息!

乡野小珥
2025-11-18 13:40:40
侯耀华北京别墅亲自做饭,灶台杂乱满墙油污,78岁穿范哲思很时尚

侯耀华北京别墅亲自做饭,灶台杂乱满墙油污,78岁穿范哲思很时尚

趣味八卦
2025-11-19 07:29:01
高市万万没想到,派“弃子”来华后,中国立场变了,又叫停2件事

高市万万没想到,派“弃子”来华后,中国立场变了,又叫停2件事

潮鹿逐梦
2025-11-17 21:59:35
薄一波晚年反省,当年不该支持此人上台,他给国家带来大麻烦

薄一波晚年反省,当年不该支持此人上台,他给国家带来大麻烦

扬平说史
2025-11-06 20:22:42
一百年里只见过4次!2025年男子在上海发现1只,一天约200人围观

一百年里只见过4次!2025年男子在上海发现1只,一天约200人围观

万象硬核本尊
2025-11-17 19:37:13
妻子逼我拿30万给小舅子买车,我62岁妈妈冷静开口:过不下去就离

妻子逼我拿30万给小舅子买车,我62岁妈妈冷静开口:过不下去就离

李子木说
2025-10-29 17:39:15
0-0险平!中国队无缘冠军,最大水货揪出,熊猫杯最终排名如下

0-0险平!中国队无缘冠军,最大水货揪出,熊猫杯最终排名如下

大秦壁虎白话体育
2025-11-18 21:53:48
勇士113-121魔术遭4坏消息!替补无稳定得分,内外线防守都被爆!

勇士113-121魔术遭4坏消息!替补无稳定得分,内外线防守都被爆!

细话篮球
2025-11-19 11:28:16
喻恩泰好友反击了!爆料史林子多次偷情出轨,并曝出露骨聊天截图

喻恩泰好友反击了!爆料史林子多次偷情出轨,并曝出露骨聊天截图

萌神木木
2025-11-18 19:36:17
不断挑拨离间!孙颖莎忍无可忍,终于道出与王曼昱“真实关系”

不断挑拨离间!孙颖莎忍无可忍,终于道出与王曼昱“真实关系”

东方不败然多多
2025-11-18 13:43:01
取消赴日旅游的中国游客:机酒已全额退款,未来出行仍在观望

取消赴日旅游的中国游客:机酒已全额退款,未来出行仍在观望

南方都市报
2025-11-18 23:22:18
中国拒绝捐款,特朗普缺席COP30,我们没有义务当冤大头

中国拒绝捐款,特朗普缺席COP30,我们没有义务当冤大头

历史求知所
2025-11-18 10:15:03
中国003型航母都要量产了,为啥东海舰队还是没分到航母?

中国003型航母都要量产了,为啥东海舰队还是没分到航母?

军武次位面
2025-11-18 17:03:53
联合国回应高市早苗言论

联合国回应高市早苗言论

每日经济新闻
2025-11-18 14:17:06
关于供应链转移这事,有业内网友说出了这些细节

关于供应链转移这事,有业内网友说出了这些细节

清晖有墨
2025-11-18 13:29:54
2025-11-19 11:40:49
CSDN incentive-icons
CSDN
成就一亿技术人
26107文章数 242182关注度
往期回顾 全部

科技要闻

一夜封神,Gemini 3让谷歌找回“碾压感”

头条要闻

女子参加模特大赛夺"广东冠军" 因突破大众审美引争议

头条要闻

女子参加模特大赛夺"广东冠军" 因突破大众审美引争议

体育要闻

结束最后一次对决,陈梦和朱雨玲笑着相拥

娱乐要闻

又反转!曝喻恩泰出轨美女律师

财经要闻

黄金税改两周,水贝低价神话终结?

汽车要闻

脱胎换骨的优秀底盘Get 新款享界S9动态驾驶体验

态度原创

教育
艺术
数码
本地
手机

教育要闻

家里欠债百万,学霸用刷题方法写网文还清债务?这才是降维打击!

艺术要闻

启功:我是画家,但书名超过了画名

数码要闻

Keychron发布三款Q HE 8K键盘新品:结合TMR与8000Hz回报

本地新闻

这档古早综艺,怎么就成了年轻人的哆啦A梦?

手机要闻

富士康已搭建苹果折叠屏专属生产线:屏幕无折痕

无障碍浏览 进入关怀版