我有一个用例,用户在其时区中选择日期和时间。在这种情况下,美国中部时间。我想将给定时区的日期转换为Epoch秒,我需要将其传递给第三方API。
到目前为止,这是我的单元测试代码的一部分:
moment.tz.add('America/Chicago');
// This value is returned by Mongoose as a Date, which is why I'm using Date() here
const publishAt = new Date('2017-07-26T12:00:00.000Z');
const publishAtEpoch = moment.tz(publishAt, 'America/Chicago').valueOf() / 1000;
结果是:
1501070400
而不是:
1501088400
根据{{3}} ,不正确
价值1501070400太早了5个小时。
如果我为日期传递一个天真的字符串:2017-07-26 12:00:00
它按预期工作。
如果我使用天真的日期:new Date('2017-07-26 12:00:00');
该值太早1小时,因为我的时区是美国东部。
我做错了什么?我认为时刻时区应该处理偏移量,占夏令时等等。
答案 0 :(得分:2)
您的publishAt
日期是使用以Z
结尾的字符串创建的,因此它表示UTC时间。正如你可以看到publishAt
(getTime()
)值,以毫秒为单位,因为Unix纪元是1501070400000
。
1501070400000
为26 July 2017 12:00:00 UTC
(请参阅0
偏移的记录
在链接表中的几秒钟内。
在我看来,问题是你期望获得1501088400000
而不是1501070400000
这是真实的"价值new Date('2017-07-26T12:00:00.000Z')
。
moment.tz('2017-07-26 12:00:00', 'America/Chicago')
提供1501088400000
,因为您要告诉我们在芝加哥解析您的字符串,而new Date('2017-07-26 12:00:00')
为您的本地时区创建日期。
请注意,时刻时区docs表示:
Unix时间戳和
Date
个对象是指特定时间点,因此在构造时使用时区偏移量没有意义。使用moment.tz(Number|Date, zone)
在功能上等同于moment(Number|Date).tz(zone)
。
这是一个显示所述结果的片段:
const publishAt = new Date('2017-07-26T12:00:00.000Z');
console.log(publishAt.getTime()); // 1501070400000
const publishAtEpoch = moment.tz(publishAt, 'America/Chicago').valueOf() / 1000;
console.log(publishAtEpoch); // 1501070400
const timeChicago = moment.tz('2017-07-26T12:00:00.000', 'America/Chicago');
console.log(timeChicago.valueOf() / 1000); // 1501088400

<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.13/moment-timezone-with-data-2012-2022.min.js"></script>
&#13;
这是一个解析毫秒(1501070400000
和1501088400000
)的片段,然后以当地时间,UTC和芝加哥时区显示值。这类似于epochconverter.com所做的,也许可以帮助您理解网站显示这些结果的原因。
const m1Local = moment(1501070400000);
console.log(m1Local.format()); // 1501070400000 local time
const m1Utc = moment(1501070400000).utc();
console.log(m1Utc.format()); // 2017-07-26T12:00:00Z
const m1Chicago = moment(1501070400000).tz('America/Chicago');
console.log(m1Chicago.format()); // 2017-07-26T07:00:00-05:00
const m2Local = moment(1501088400000);
console.log(m2Local.format()); // 1501088400000 local time
const m2Utc = moment(1501088400000).utc();
console.log(m2Utc.format()); // 2017-07-26T17:00:00Z
const m2Chicago = moment(1501088400000).tz('America/Chicago');
console.log(m2Chicago.format()); // 2017-07-26T12:00:00-05:00
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.13/moment-timezone-with-data-2012-2022.min.js"></script>
&#13;
作为附加信息,请注意,时刻有unix()
方法:
moment#unix
输出一个Unix时间戳(自Unix Epoch以来的秒数)。此值被覆盖到最接近的秒,并且不包括毫秒组件。
如果您希望避免1000
除以valueOf()
返回的值。
可能有用的其他阅读材料:Local vs UTC vs Offset指南,时区标记info page。