Chrome 和 Firefox 对 "invalid" DST 时间的处理方式不同

Chrome and Firefox exhibit different handling of an "invalid" DST time

最小的例子:

var test = new Date();
test.setMonth(3);
test.setDate(3);
test.setHours(2);
test.getUTCHours()`

在 Firefox 上我得到“7”,Chrome 得到“8”(我认为是正确答案)。

DST 临近,我的任务是解决 javascript 中的各种变化问题。我不确定如何处理这个。时间快了 1 小时,所以我们将从 1:59:59 到 3:00:00 完全跳过凌晨 2 点。问题是我们有多个没有这个概念的日期时间选择器(没关系),所以你仍然可以 select 凌晨 2 点。我希望当我从凌晨 2 点开始构建日期时,它会被推到凌晨 3 点,所以 2:05 变成 3:05。 Chrome 处理得很好,但 Firefox 似乎将其推回到 1:05。 UTC 关闭一小时,但是当您使用时区进行格式化时,它将显示为 1:05.

我该如何解决这个问题?我认为答案只是 "momentjs",但我想了解为什么会有所不同。

你是对的。 Spring 向前 DST 转换将创建 无效 本地时间间隔。 JavaScript 要么向前推进,要么向后推进,按间隙量。它的走向在 ECMAScript 规范中没有定义,因此不同的浏览器做的不同。恕我直言,移动 forward 最符合逻辑(因为时间向前移动),但有些人认为应该优先使用 "standard" 时间。

对于 Fall Back DST 转换,有一段本地时间重叠的时间段,其中本地时间可能 不明确 。 JavaScript 会将其映射到第一个实例(夏令时)或第二个实例(标准时间)。同样,有些人认为应该优先选择 "standard" 时间,但按实际发生的时间顺序排列更符合逻辑 - 这意味着选择 daylight 实例。

桌面浏览器目前的格局如下:

在过去的几年里,我多次更新了这些图表,因为即使在浏览器中,它也会在不同版本之间发生变化。我为 my Pluralsight course 制作的第一个版本看起来很不一样。许多浏览器已经从行为的一侧翻转到另一侧。所以在做任何假设时要小心——旧的浏览器很可能与这张图表有所不同。我也没有展示大量的移动网络浏览器。

现在你问的是如何处理这个问题。不幸的是,没有太多好的选择。您提到了 moment.js,它确实是一个很棒的日期和时间库 - 但由于它目前依赖于引擎盖下的 Date 对象,因此它没有解决这个特定问题。它继承了浏览器的任何行为。 (这是一个已知问题,我们正在努力解决。)

更新

我以前写过一些函数来展示如何解决这个问题。如果您查看编辑历史记录,您仍然可以找到这些。不幸的是,我在使用 isShiftedForwardisShiftedBackward 方法时犯了一个严重错误。尽管如果时间戳已移动,它们会返回 true,但如果给定紧邻转换的有效时间戳,它们也会(错误地)返回 true。 (即向前移动时在后一个小时,或向后移动时在前一个小时。)

因此,我从答案中删除了这些功能。如果不知道创建 Date 对象的原始值,就无法避免这种情况。他们无法单独使用 Date 对象。