指南区域旨在帮助开发人员学习如何更好地与日期和时间问题域以及 Moment Timezone 库进行交互。 这些指南特别限于有关时区的概念以及 Moment Timezone 如何处理它们。
有关更一般的日期和时间建议,请参阅 核心 Moment.js 指南。
通常,人们对时区和 UTC 偏移量之间的差异感到困惑。
核心 Moment.js 文档有 关于这个主题的指南,值得先阅读。 从逻辑上讲,它属于 Moment Timezone 的指南,但它早于本指南部分很多年,移动它会破坏互联网上的很多链接。
For an in depth description of zones vs offsets, see the Stack Overflow tag.
Moment Timezone 通过使用预编译的时区数据增强核心 Moment.js 功能。
本节介绍数据的来源、限制以及现实世界时区规则的一些怪癖。 API 文档 中描述了数据格式的技术细节。
Moment Timezone 中的所有时区数据均来自 IANA 时区数据库 ("tzdb")。 Moment Timezone 直接使用来自 tzdb 的默认数据,仅使用已发布的版本。 库所做的唯一更改是将数据转换为 自定义 JSON 格式,并可选择限制使用多少年的数据。
任何对已编译数据文件进行更改而不是从 tzdb 版本派生的拉取请求都将被拒绝。
如果您认为 Moment Timezone 使用的数据不正确,那么理想的操作顺序是:
默认情况下,Moment Timezone 包括来自 IANA 时区数据库 ("tzdb") 的所有数据。 这涵盖了某些区域早在 1800 年代的过去数据,以及直到 2499 年的未来数据。 这通常比大多数应用程序所需的数据更多,因此也有一些预构建的数据包可用,但年份范围更有限。 这些列在 项目主页 和 "何处使用" 文档 上(或者您可以使用 工具函数 创建自定义日期范围)。
这些有限的捆绑包经常出现的一个问题是: 数据范围之外的日期会怎样? 例如,如果加载的数据仅涵盖 2012 年到 2022 年,并且计算了 2023 年或 2010 年的日期,那么计算出的该日期的 UTC 偏移量是多少?
由于 data format 的结构,假设数据范围边界处的时区规则无限扩展到过去和未来。 这会产生以下行为:
例如,假设一个项目正在使用仅涵盖 2015 年到 2025 年的数据文件,并且想要计算 2026 年某个时间在澳大利亚悉尼的时间。
Australia/Sydney
的基准(标准)偏移量为 UTC+10:00
。
悉尼的夏令时 (DST) 适用于 10 月至次年 3 月,偏移量为 UTC+11:00
。UTC+11:00
的偏移量。 这是正确的,但只是偶然。
计算 2026 年 3 月之后的日期仍将得到 UTC+11:00
的偏移量,即使实际值应该是 UTC+10:00
。
这是错误开始出现的时候。解决这些计算问题的最佳方法是确保您使用的数据范围涵盖项目所需的所有日期。
使用夏令时 (DST) 的时区因实现时间跳跃的时间而异。 您不应该假设您熟悉的本地时区规则适用于其他时区。
经常引起开发人员注意的一个区别是,某些区域会在午夜更改时钟。
一个很好的例子来自 2021 年的约旦 (Asia/Amman
):
2021-03-25 23:59:59
后一秒是 2021-03-26 01:00:00
(DST 开始)。2021-10-29 00:59:59
后一秒是 2021-10-29 00:00:00
(DST 停止)。这造成了 3 月 26 日午夜没有发生,而 10 月 29 日午夜发生了两次的情况。
如 "解析歧义" 文档 中所述,Moment Timezone 解释了这些奇怪之处。 但是,当应用程序对时间跳跃做出其他假设时,尤其是关于一天的开始时,它们仍然可能存在错误。 所以请注意,一天并不总是从午夜开始。