momentjs toDate-不同客户端/浏览器上的不同输出

时间:2018-10-22 15:04:09

标签: javascript date timezone momentjs timezone-offset

我使用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),但是日期(小时)不同吗?

2 个答案:

答案 0 :(得分:4)

您要检查的是 current UTC偏移量,而不是1980时刻实例的偏移量。我的猜测是,如果您在{em>那个上使用moment(dateString, 'YYYY-MM-DD')并调用utcOffset,则在不同的浏览器上会得到不同的偏移量。

我敢打赌,自1980年以来,您所在区域的规则已更改(例如,DST的时间已更改,DST的添加或取消,或者标准偏移量甚至已更改)。浏览器正确获取历史区域数据的程度不同,这会导致解释日期字符串时出错。我怀疑Firefox已为您的区域修复了其历史区域数据库,从而导致浏览器的新版本中出现不同的行为。

答案 1 :(得分:3)

您显示的偏移量是针对当前日期和时间的,而不是针对提供的日期的。如果您将中间行更改为登录moment(dateString, 'YYYY-MM-DD').utcOffset(),则应该看到较旧的Firefox 52的结果是60,而不是120

造成这种差异的因素有:

  • 您所在时区的夏时制规则在1980年与现在不同。假设维也纳(根据您的用户个人资料),DST的开始时间是1980年4月6日(reference here)的00:00,这是4月的第一个星期日。维也纳目前的(2018)规则是3月的最后一个星期日,即2018年3月25日(reference here)。

  • ECMAScript 5.1 (section 15.9.1.8) 和更早的版本要求浏览器始终假设当前的DST规则一直有效-即使实际上并非如此。在ECMAScript 6 / 2015 (section 20.3.1.8) 中,此问题已得到纠正。

  • ECMAScript 2015在Firefox中从版本54开始实施。由于您正在测试版本52,因此您看到的是旧行为。

  • 由于这种特殊的DST更改恰好在午夜时分,并且是向前跳的过渡,因此1980-04-06T00:00无效。该时间段中当天的第一时刻为1980-04-06T01:00。当您传递仅日期的值时,Moment会为您解决此问题。在当前浏览器(62,而不是52)中,如果您立即致电.format(),您应该会看到1980-04-06T01:00:00+02:00。请注意,该时间已经是夏令时(DST),具有UTC + 02:00偏移。 1980-04-05T23:00:00Z转换为UTC,因此与示例中显示的正确数据保持一致。

长话短说,使用最新浏览器的原因很多。这就是其中之一。