moment.tz在设置“Etc/GMT[+|-]HH:MM”时区时出现问题

4

我已经为此苦恼了一整天,检查了源代码,这似乎是由于强大的JavaScript moment.tz库引起的问题:

每当我传入一个时区标识符"Etc/GMTtime-value"时,返回的moment.tz对象会被乘以-1,我认为这是一个格式("Z")值。

例如:

var pacificTime = moment.tz("2016-09-29 21:00:00","America/Los_Angeles");
pacificTime.format("YYYY-MM-DD HH:mm:ss Z z");

输出结果:"2016-09-29 21:00:00 -07:00 PDT"

这里一切正常。

现在,使用相同的时区(GMT-7):

var GMT_minus_7 = moment.tz("2016-09-29 21:00:00","Etc/GMT-7");
GMT_minus_7.format("YYYY-MM-DD HH:mm:ss Z z");

输出:"2016-09-29 21:00:00+07:00 GMT-7"

粗体值始终是我认为它应该是的负值:传入“Etc/GMT+5”返回“-5:00”的值。

这让我很头疼,因为我正在处理具有日期/时间记录的网页,其中包含一个整数“GMT偏移”值,我只需将其转换为“Etc/GMT” + 偏移值并传递给moment.tz进行时区转换。然后,我需要对该值进行进一步操作(添加天数、显示“Z”格式化值等),但此问题已妨碍了进一步工作。

这是moment.tz解析“Etc/GMT”时区值的缺陷,还是我对时区格式有什么基本误解?


我进行了进一步的测试,似乎是moment.tz中的格式错误;我运行了以下测试:GMT_minus_7.utc().format("YYYY-MM-DD HH:mm:ss Z z")并得到响应"2016-09-29 14:00:00 +00:00 UTC"UTC转换正确地从21:00减去了7个小时,以给出14:00。因此,对于这种用例,“Z”值的格式可能不正确。 - Perry Pederson
关于您的评论 - 您调用了.utc(),因此在此之后的任何内容都将是UTC时间,即+00:00 - Matt Johnson-Pint
1个回答

2
IANA数据库中的标识符(例如Etc/GMT-7)故意颠倒了它们的偏移量。这是这种标识符设计的一部分。详见维基百科上的说明tz数据库源代码中的说明。(基本上,这源于在某些环境下需要向后兼容较旧的POSIX标准的需求。)
然而,在使用固定时区偏移量时,您在Moment.js中根本不需要使用这些标识符。实际上,您根本不需要moment-timezone扩展程序。
// the parseZone method will retain the offset provided
var a = moment.parseZone("2016-09-29 21:00:00 -07:00");

// or, you can set the offset explicitly like this:
var b = moment.utc("2016-09-29 21:00:00").utcOffset("-07:00", true);

// or like this if you prefer:
var c = moment.utc("2016-09-29 21:00:00").utcOffset(-7, true);

对于bc,请注意需要使用true参数来保留给定的本地时间。同时请注意我使用moment.utc(...)来最初解析该字符串。也可以使用moment(...),但这样可能会导致本地时区的夏令时转换干扰中间值。
此外,请确保您认识到America/Los_Angeles在是否实行夏令时时会在-8和-7之间交替变化。这就是为什么需要moment-timezone提供何时切换偏移量的规则。

太棒了!非常感谢! - Perry Pederson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接