我们应该在服务器端将 Z 附加到它们吗?
TL;DR是的,您可能应该这样做。
遗憾的是,在没有时区的情况下正确处理日期和日期/时间多年来一直在变化——无论是在规范方面,还是在 JavaScript 引擎对规范的遵守方面。
当这个答案最初是在 2013 年编写的时,ES5规范(第一个为 JavaScript 定义了日期/时间格式,这意味着它是ISO-8601的子集)很明确:没有时区 = UTC:
缺席时区偏移的值为“Z”。
但这与 ISO-8601 不一致,其中没有时区指示符意味着“本地时间”。一些实现从未实现 ES5 的含义,而是坚持使用 ISO-8601。
在ES2015(又名“ES6”)中,它被更改为匹配 ISO-8601:
如果不存在时区偏移量,则日期时间将被解释为本地时间。
但是,这会导致与现有代码的不兼容问题,尤其是对于仅日期形式的2018-07-01
,因此在ES2016中再次对其进行了更改:
当时区偏移不存在时,仅日期形式被解释为 UTC 时间,而日期时间形式被解释为本地时间。
Sonew Date("2018-07-01")
被解析为 UTC,但new Date("2018-07-01T00")
被解析为本地时间。
自 ES2017 和即将到来的 ES2018 以来,它一直保持一致;这是当前编辑草稿的链接,它不再具有确切的文本,但仍然以相同的方式定义它(尽管恕我直言不太清楚)。
你可以在这里测试你当前的浏览器:
function test(val, expect) {
var result = +val === +expect ? "Good" : "ERROR";
console.log(val.toISOString(), expect.toISOString(), result);
}
test(new Date("2018-07-01"), new Date(Date.UTC(2018, 6, 1)));
test(new Date("2018-07-01T00:00:00"), new Date(2018, 6, 1));
截至 2021 年 9 月的状态:
- 现代版本的 Firefox、Chrome 和 Safari 都做到了这一点,包括 iOS 浏览器(目前都使用 Apple 的 JavaScriptCore JavaScript 引擎,因为 Apple 不会让他们使用自己的 JIT)
- IE11 做对了(有趣的是)
截至 2018 年 4 月的状态:
- IE11 做对了(有趣的是)
- Firefox 做对了
- Chrome 65(桌面,Android)做对了
- Chrome 64 (iOS v11.3) 获取日期/时间格式错误(解析为 UTC)
v11.3 中的 iOS Safari 获取日期/时间格式错误(解析为 UTC)
奇怪的是,我在 v6.4(Chrome 64 中的 v8)和 v6.5(Chrome 65 中的 v8)之间修复的 v8 问题列表中找不到问题;我只能找到这个仍然存在但似乎已修复的问题。