改变不同浏览器上的不同行为

时间:2018-12-28 11:37:25

标签: javascript date momentjs dst epoch

让以下代码段:

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中运行该代码段,看看结果是否相同。

不会。

(这里是https://codepen.io/anon/pen/yZMqrV的整个游乐场)

1 个答案:

答案 0 :(得分:4)

“ MomentJS浏览器是否独立?”这个问题的答案。可能是“否”。 从片刻获取长整型可能取决于您使用的浏览器。 同样会影响JavaScript的Date对象。

此问题与世界上每个国家/地区的DST历史应用程序有关,然后与历史时区偏移量有关,直到最近版本的ECMAScript才观察到。 因此,旧版本的浏览器(例如Firefox 61.0.1和Microsoft Edge)并未正确覆盖DST规则在全球所有不同位置的影响。

要解决此问题,您必须使用MomentJS的.utc()方法(如我的回答中VincenzoC的评论)。

因此,以下代码在每种浏览器中均有效:它始终返回相同的时间(Epoch Time),并且每次都“标准化” DST(始终为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的相关问题)

您可以在这里使用一些游乐场:Codepen1Codepen2