在不同的浏览器上出现不同的行为
Posted
技术标签:
【中文标题】在不同的浏览器上出现不同的行为【英文标题】:Moment different behaviour on different browsers 【发布时间】:2019-05-26 05:55:11 【问题描述】:让下面的sn-p:
var dateJS = new Date("1950-09-09T23:00:00.000Z");
var dateMoment = moment("1950-09-09T23:00:00.000Z");
console.log("javascript Epoch Time:", dateJS.valueOf());
console.log("Moment Epoch Time:", dateMoment.valueOf());
console.log("Is DST?", dateMoment.isDST());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.23.0/moment.min.js"></script>
如果您使用某些 Firefox 版本(例如 Firefox 61.0.1)或 Microsoft Edge 运行它,您会收到 Is DST? true
。相反,如果您使用其他 Firefox 版本(例如 64.0)或任何 Chrome 运行它,您会得到Is DST? false
。
可能是什么原因?
新片段:
var mar1947 = moment("1947-03-20T00:00:00.000Z");
var sep1947 = moment("1947-09-10T00:00:00.000Z");
var mar1950 = moment("1950-03-20T00:00:00.000Z");
var sep1950 = moment("1950-09-10T00:00:00.000Z");
var mar2019 = moment("2019-03-20T00:00:00.000Z");
var sep2019 = moment("2019-09-10T00:00:00.000Z");
console.log("March 1947: Epoch Time / DST:", mar1947.valueOf(), mar1947.isDST());
console.log("September 1947: Epoch Time / DST:", sep1947.valueOf(), sep1947.isDST());
console.log("March 1950: Epoch Time / DST:", mar1950.valueOf(), mar1950.isDST());
console.log("September 1950: Epoch Time / DST:", sep1950.valueOf(), sep1950.isDST());
console.log("March 2019: Epoch Time / DST:", mar2019.valueOf(), mar2019.isDST());
console.log("September 2019: Epoch Time / DST:", sep2019.valueOf(), sep2019.isDST());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.23.0/moment.min.js"></script>
请先用 Chrome 再用 Firefox 61.0.1 或 Microsoft Edge 运行 sn-p,看看结果是否相同。
不会的。
(这里是完整的游乐场https://codepen.io/anon/pen/yZMqrV)
【问题讨论】:
我在 Chrome v71 中得到Is DST? true
,而不是 Is DST? false
。 (在 Firefox 64 和 Edge 中也可以得到 true
,但你说你也是……)
我在 Chrome 71 上获得 false
,在 Firefox 64 上获得 false
,在 Edge 上获得 true
(Win 10,欧洲/罗马时区)。我注意到 dateMoment.format()
在 Chrome 上输出 1950-09-10T00:00:00+01:00
,而我在 Edge 上得到 1950-09-10T01:00:00+02:00
。您对最新版本的时刻(2.22.2)有同样的问题吗?是否使用moment.utc
解析输入更改结果?
@smartmouse 感谢您的反馈,使用 moment 2.23.0 和 moment.utc("1950-09-09T23:00:00.000Z")
即使在 Edge 上我也会得到 Is DST? false
。
我不得不承认,如果 Moment 的时区文件涵盖了 1950 年在全球所有不同地点生效的 DST 规则,我会感到相当惊讶...
可能是 Browsers, time zones, Chrome 67 Error 的副本,即这是历史时区偏移的问题,直到最近版本的 ECMAScript 才观察到。我住的地方没有夏令时,所以不是问题。 :-)
【参考方案1】:
“MomentJS 浏览器是否独立?”问题的答案可能是“不”。
从 Moment 日期获取 Long 可能取决于您使用的浏览器。
这同样会影响 Javascript 的 Date
对象。
此问题与世界上每个国家/地区的历史 DST 应用程序有关,然后与历史时区偏移有关,直到最新版本的 ECMAScript 才观察到。 如此旧的浏览器,例如 Firefox 61.0.1 和 Microsoft Edge,并没有正确覆盖在全球所有不同地区有效的 DST 规则。
要解决这个问题,您必须使用 MomentJS 的 .utc()
方法(正如 VincenzoC 在我的回答中的评论)。
因此,以下代码适用于每个浏览器:它始终返回相同的时间(纪元时间),并且每次都“标准化”夏令时(始终为 false):
var mar1947 = moment("1947-03-20T00:00:00.000Z").utc().startOf('day');
var sep1947 = moment("1947-09-10T00:00:00.000Z").utc().startOf('day');
var mar1950 = moment("1950-03-20T00:00:00.000Z").utc().startOf('day');
var sep1950 = moment("1950-09-10T00:00:00.000Z").utc().startOf('day');
var mar2019 = moment("2019-03-20T00:00:00.000Z").utc().startOf('day');
var sep2019 = moment("2019-09-10T00:00:00.000Z").utc().startOf('day');
console.log("March 1947:", mar1947.valueOf(), mar1947.isDST());
console.log("September 1947:", sep1947.valueOf(), sep1947.isDST());
console.log("March 1950:", mar1950.valueOf(), mar1950.isDST());
console.log("September 1950:", sep1950.valueOf(), sep1950.isDST());
console.log("March 2019:", mar2019.valueOf(), mar2019.isDST());
console.log("September 2019:", sep2019.valueOf(), sep2019.isDST());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.23.0/moment.min.js"></script>
请注意,如果您在其他方法之后(而不是之前)使用此方法,例如 startOf()
(请参阅 github 上的相关问题),此方法将无法正常工作
在这里你可以使用一些游乐场:Codepen1,Codepen2
【讨论】:
以上是关于在不同的浏览器上出现不同的行为的主要内容,如果未能解决你的问题,请参考以下文章
同样的网站,在不同的服务器上,运行结果为啥不一样呢?一个很正常,一个就出现一些错误!