如何从 moment 对象中获取 "Standard" 时区字符串?

How do I get the "Standard" timezone string from a moment object?

我正在做一个 asp.net 项目,处理服务器上的数据库和在客户端上显示它们的小部件之间的各种日期和时间。我正在尝试使用 moment.js.

当我调试 moment 对象时,我看到以下信息:

我需要使用 "Pacific Daylight Time" 部分,因为这是 TimeZoneInfo c# class(我在后端使用的)唯一接受的字符串格式。

我如何获得那条数据?

我通读了文档和指南,没有任何内容与时区的 "Standard" 名称相关,只有像 "America/Los Angeles" 这样的城市名称,这是不合适的。我 可以 制作一个字典,将城市名称映射到标准名称,但这需要相当长的时间并且很痛苦,所以我想找到正确的方法来做到这一点。

使用字符串解析或 C# 库

我找到了 2 个解决方案来获取我需要的数据,但是这两个解决方案都非常糟糕而且很老套。

  1. 在前端,调用 moment 的 .toString() 函数和模式匹配结果以获取时区名称。

这可以用正则表达式或 .split() 来完成,并且它可以工作,假设日期字符串的格式永远不会改变。它看起来像:

var timeZoneName = momentDate._d.toString().split("(")[1].split(")")[0];
//timeZoneName now holds "Pacific Daylight Time"

将该值传递到后端后,您仍然需要将“Daylight”替换为“Standard”以创建 TimeZoneInfo 实例。

  1. 在后端,使用外部库为您做映射。

我找到的两个库是TimeZoneNames and TimeZoneConverter。这些可以采用 IANA 风格的名称并将它们与 Windows 标准等价物相匹配。我像这样使用 TimeZoneConverter:

localTZName = TZConvert.IanaToWindows(tzName);
TimeZoneInfo localTimeZone = TimeZoneInfo.FindSystemTimeZoneById(localTZName);

tzName是在前端使用moment.tz.guess()的结果。这种方法非常有效,但它是预先构建的,相当于制作从一种样式到另一种样式的地图,所以我很高兴有人经历了这种痛苦,所以我不必这样做。

这两种解决方案都很糟糕,但似乎没有办法解决它们

第一个解决方案依赖于希望 moment 的字符串表示永远不会改变,而且 moment 确实应该有一种方法来获取这个特定的数据而不必将其从字符串中删除,特别是因为 他们已经经历了查找数据的麻烦,只是不让你拥有它。

第二种解决方案只是暴力映射。不雅、丑陋,但它有效,虽然它确实感觉它应该是 moment.tz.js 或 TimeZoneInfo 或两者的原生内容。

脱节似乎是因为 moment.js 拒绝承认 Windows 存在,而 Windows 拒绝承认时区是复杂的野兽,有很多历史可以影响准确约会。