【问题标题】:How to obtain unix timestamps for same date in 2 different time zones with moment.js?如何使用 moment.js 在 2 个不同时区中获取同一日期的 unix 时间戳?
【发布时间】:2020-09-16 19:43:55
【问题描述】:

我正在开发一个应用程序,用户可以在其中选择他们记录时间的时区。但在内部,我想将时间存储为 unix 时间戳。

假设我有一个日期“2016-01-01 1:00 pm”。如果我将此日期存储在 CDT(美国/芝加哥)中,我的理解是生成的 unix 时间戳应该与我在 MDT(美国/丹佛)中存储相同日期不同。但是,我在两个日期都得到了相同的 unix 时间戳,我无法理解为什么。

var chicagoDate = moment('2016-01-01 1:00 pm').tz('America/Chicago');
var denverDate = moment('2016-01-01 1:00 pm').tz('America/Denver');

chicagoDate.format();
// "2016-01-01T07:00:00-06:00"
denverDate.format();
// "2016-01-01T06:00:00-07:00"

到目前为止,这证实了这两个日期彼此不同,如使用 format() 获得的 UTC 表示所示。但这是我感到困惑的地方:

chicagoDate.unix();
// 1451653200
denverDate.unix();
// 1451653200

2 个不同的 UTC 日期不应该导致 2 个不同的 unix 时间戳吗?

【问题讨论】:

  • unix 时间戳是相同的,您唯一要做的就是根据时区更改日期字符串的显示方式。即使 "2016-01-01T07:00:00-06:00" !== "2016-01-01T06:00:00-07:00" 都代表相同的 UTC 日期 2016-01-01T00:00:00 -00:00,这就是为什么你总是会看到相同的 unix 时间戳值。
  • UTC 是时间标准,而不是格式。 moment#format 的默认格式是主机或指定时区中的 ISO 8601,以适用者为准。另请注意,由于您没有提供解析格式,moment.js 将回退到内置解析器,因此结果可能是无效的日期(例如 Safari)。

标签: javascript datetime momentjs unix-timestamp


【解决方案1】:

在:

moment('2016-01-01 1:00 pm').tz('America/Chicago');

没有解析格式参数,所以 moment.js 会查看格式是否是它可以在没有格式的情况下解析的格式。它不能,所以它回退到内置解析器,就像你写的一样:

moment(new Date('2016-01-01 1:00 pm')).tz('America/Chicago');

并在控制台中发出警告:

弃用警告:提供的值不是可识别的 RFC2822 或 ISO 格式。 moment 构建回退到 js Date(),它在所有浏览器和版本中并不可靠......

Safari 至少会将其解析为无效日期(时间戳),因此您应该包含解析格式:

moment(new Date('2016-01-01 1:00 pm', 'YYYY-MM-DD h:mm a')).tz('America/Chicago');

其次,字符串被解析为本地,因为没有与时间戳关联的时区。因此,两行代码产生完全相同的时间值(即从纪元偏移)并且产生的两个日期实际上是相同的。

tz 的调用设置了用于所有后续操作的时区,因此输出显示不同的时间,因为在格式化阶段应用了不同的偏移量。被格式化的实际日期仍然实际上是相同的。

如果您希望将字符串解析为另一个时区,您需要在解析阶段手动将其包含在字符串中(例如,'-06:00' 或其他),或者使用像 Luxon 这样的库具有 IANA 位置(例如“美国/芝加哥”)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-08
    • 1970-01-01
    • 2013-07-16
    • 2022-06-14
    • 2020-03-27
    • 1970-01-01
    • 2015-03-23
    • 1970-01-01
    相关资源
    最近更新 更多