您可以非常轻松地使用 moment-timezone 可靠地转换当地时间:
var original = moment.tz('2017-12-23T09:00:00', 'America/Los_Angeles');
var easternUS = original.clone().tz('America/New_York');
var centralEU = original.clone().tz('Europe/Berlin');
var westAUS = original.clone().tz('Australia/Perth');
var japan = original.clone().tz('Asia/Tokyo');
// etc.
(.format(...)
用于生成具有所需输出的字符串。)
您还可以使用任何正常的 Moment 函数轻松计算提前一小时的时间。
var earlierUTC = original.clone().utc().subtract(1, 'hour');
var earlierEastern = easternUS.clone().subtract(1, 'hour');
是的,如您所见,您需要存储的只是2017-12-23T09:00:00
和America/Los_Angeles
。
可能会考虑使用偏移量存储事件时间,例如2017-12-23T09:00:00-08:00
,但您会遇到一些问题:
如果事件每月再次发生怎么办?当 DST 在 3 月开始时,您必须决定是否将当地时间保持在上午 9 点并将偏移量更改为 -7,或者最初的意图是否是等效的 UTC 时间(17:00Z),这将移动当地时间到上午 10 点。
如果政客在事件发生前更改时区或 DST 规则怎么办?今年在加利福尼亚不太可能发生这种情况,但它确实在短时间内发生,并且在全球范围内具有一定的规律性。请参阅我的博客文章On the Timing of Time Zone Changes。即使在加利福尼亚——假设这是一个发生在夏天的年度活动,然后说像这样的法案已通过成为法律——你的抵消是错误的。
有一点你应该考虑。如果事件当地时间无效或不明确怎么办?
无效时间发生在 spring-forward 转换上。例如,时钟从 1:59 移动到 3:00,但您有 2:30 的事件时间。这对于单个事件不太可能发生,但对于重复发生的事件很容易发生。您必须决定如何处理此问题,但如果您不确定,那么我建议您将当地时间提前一段时间。所以事件将在当天的 3:30,然后在下一次发生时回到 2:30。
回退转换时会出现模棱两可的时间。例如,时钟从 1:59 移回 1:00。如果您的活动在 1:30 运行,则您必须决定是在第一个实例上运行,还是在第二个实例上运行,或同时在这两个实例上运行。在大多数情况下,我建议在第一个实例上运行(恰好是白天时间,而不是标准时间)。
如果事件真的只运行一次,并且可能是在回退转换期间,那么可以通过以 UTC 或本地时间记录事件时间并带有偏移量来消除歧义。正如我之前提到的,请注意时区规则的变化。
Moment-timezone 在其转换过程中自动应用上述建议,因此除非您有理由偏离 - 您不必担心。