momentjs toDate - 不同 clients/browsers 上的不同输出
momentjs toDate - different output on different clients/browsers
我使用 momentjs 解析日期字符串并将其转换为原生 JavaScript 日期:
let dateString = '1980-04-06';
console.log(moment().utcOffset());
console.log(moment(dateString, 'YYYY-MM-DD').toDate());
<script src="https://cdn.jsdelivr.net/npm/moment@2.22.2/moment.min.js"></script>
客户端 1(Firefox 62) 上的输出是
120
Date 1980 - 04 - 05 T23: 00: 00.000 Z
客户端 2(Firefox 52 ESR) 上的输出是
120
Date 1980 - 04 - 05 T22: 00: 00.000 Z
有人可以解释一下,为什么 utcOffset 相同(new Date().getTimezoneOffset()
在两个客户端上也打印 -120
),但日期(小时)不同?
您正在检查 当前 UTC 偏移量,而不是 1980 时刻实例的偏移量。我的猜测是,如果你在 that 上使用 moment(dateString, 'YYYY-MM-DD')
并调用 utcOffset
,你会在不同的浏览器上获得不同的偏移量。
我敢打赌,您所在区域的规则自 1980 年以来发生了变化(例如,DST 的时间可能发生了变化,或者 DST 已被添加或取消,或者标准偏移量可能甚至发生了变化) .浏览器在正确获取历史区域数据的程度上各不相同,这会导致错误解释日期字符串。我怀疑 Firefox 为您的区域修复了他们的历史区域数据库,导致在新版本的浏览器中出现不同的行为。
您显示的偏移量是针对当前 日期和时间的,而不是针对提供的日期。如果您将中间行更改为记录 moment(dateString, 'YYYY-MM-DD').utcOffset()
,您应该会看到在较旧的 Firefox 52 中的结果是 60
而不是 120
.
解释这种差异的因素是:
您所在时区的夏令时规则在 1980 年与今天不同。假设维也纳(根据您的用户个人资料),1980 年 DST 的开始时间是 4 月 6 日 00:00 (reference here) which is the first Sunday in April. The current (2018) rule for Vienna is the last Sunday in March, which would be March 25th 2018 (reference here)。
ECMAScript 5.1 (section 15.9.1.8) and earlier required browsers to always assume the current DST rule was in effect for all time - even if this was not actually what happened. This was corrected in ECMAScript 6 / 2015 (section 20.3.1.8) .
ECMAScript 2015 从版本 54 开始在 Firefox 中实现。由于您正在测试版本 52,因此您看到的是旧行为。
由于这个特定的 DST 更改恰好在午夜敲响,并且它是一个 spring-forward 转换,因此,1980-04-06T00:00
无效。该时区当天的第一时刻是 1980-04-06T01:00
。当您传递一个仅限日期的值时,Moment 会为您解决这个问题。在当前的浏览器中(62,不是 52),如果你现在调用 .format()
,你应该看到 1980-04-06T01:00:00+02:00
。请注意,该时间已经采用 DST,具有 UTC+02:00 偏移量。转换为 UTC 是 1980-04-05T23:00:00Z
,因此与您的示例中看到的正确数据对齐。
长话短说,使用最新浏览器的原因有很多。这是其中之一。
我使用 momentjs 解析日期字符串并将其转换为原生 JavaScript 日期:
let dateString = '1980-04-06';
console.log(moment().utcOffset());
console.log(moment(dateString, 'YYYY-MM-DD').toDate());
<script src="https://cdn.jsdelivr.net/npm/moment@2.22.2/moment.min.js"></script>
客户端 1(Firefox 62) 上的输出是
120
Date 1980 - 04 - 05 T23: 00: 00.000 Z
客户端 2(Firefox 52 ESR) 上的输出是
120
Date 1980 - 04 - 05 T22: 00: 00.000 Z
有人可以解释一下,为什么 utcOffset 相同(new Date().getTimezoneOffset()
在两个客户端上也打印 -120
),但日期(小时)不同?
您正在检查 当前 UTC 偏移量,而不是 1980 时刻实例的偏移量。我的猜测是,如果你在 that 上使用 moment(dateString, 'YYYY-MM-DD')
并调用 utcOffset
,你会在不同的浏览器上获得不同的偏移量。
我敢打赌,您所在区域的规则自 1980 年以来发生了变化(例如,DST 的时间可能发生了变化,或者 DST 已被添加或取消,或者标准偏移量可能甚至发生了变化) .浏览器在正确获取历史区域数据的程度上各不相同,这会导致错误解释日期字符串。我怀疑 Firefox 为您的区域修复了他们的历史区域数据库,导致在新版本的浏览器中出现不同的行为。
您显示的偏移量是针对当前 日期和时间的,而不是针对提供的日期。如果您将中间行更改为记录 moment(dateString, 'YYYY-MM-DD').utcOffset()
,您应该会看到在较旧的 Firefox 52 中的结果是 60
而不是 120
.
解释这种差异的因素是:
您所在时区的夏令时规则在 1980 年与今天不同。假设维也纳(根据您的用户个人资料),1980 年 DST 的开始时间是 4 月 6 日 00:00 (reference here) which is the first Sunday in April. The current (2018) rule for Vienna is the last Sunday in March, which would be March 25th 2018 (reference here)。
ECMAScript 5.1 (section 15.9.1.8) and earlier required browsers to always assume the current DST rule was in effect for all time - even if this was not actually what happened. This was corrected in ECMAScript 6 / 2015 (section 20.3.1.8) .
ECMAScript 2015 从版本 54 开始在 Firefox 中实现。由于您正在测试版本 52,因此您看到的是旧行为。
由于这个特定的 DST 更改恰好在午夜敲响,并且它是一个 spring-forward 转换,因此,
1980-04-06T00:00
无效。该时区当天的第一时刻是1980-04-06T01:00
。当您传递一个仅限日期的值时,Moment 会为您解决这个问题。在当前的浏览器中(62,不是 52),如果你现在调用.format()
,你应该看到1980-04-06T01:00:00+02:00
。请注意,该时间已经采用 DST,具有 UTC+02:00 偏移量。转换为 UTC 是1980-04-05T23:00:00Z
,因此与您的示例中看到的正确数据对齐。
长话短说,使用最新浏览器的原因有很多。这是其中之一。