8

我从 .Net 服务返回 UTC 日期/时间列表,格式如下:

"2013-07-09 19:48:07 +00:00".

在客户端,我将这些字符串值中的每一个转换为相应的基于 UTC 的时刻,就像这样

var fooUtc = new moment.utc(serverDateTimeString)

在页面上,有一个下拉列表,其中包含用户可以更改的时区列表。这些与时区对象的集合相关联,如下所示:

{
    id: "Central Standard Time",
    label: "(UTC-06:00) Central Time (US & Canada)",
    observesDaylightSavings: true,
    baseUtcOffset: {
        asHours: -6,
        asMinutes: -360,
        asText: "-06:00"
}

然后,我显示通过所选时区偏移的每个时刻,如下所示:

fooUtc.local().zone(selectedTimeZone.baseUtcOffset.asMinutes).format()

但是,结果没有考虑夏令时,因为来自 .Net 的时区数据不区分 dst 和非 dst 偏移量。

有没有办法使用 moment.js 或新的 moment-timezone 位来完成这项工作?我认为如果我可以将标准 UTC 偏移名称(例如:“中部标准时间”)映射到给定时区的Olson DB 标识符(例如:“America/Chicago”),这是可能的,但如果有更简单的方法,请让我知道。

4

1 回答 1

6

您应该探索在 .Net 端使用Noda Time ,在客户端使用moment-timezone,传递 IANA/Olson 时区 ID。

如果您想在下拉列表中坚持使用 Windows 时区 ID,则可以使用嵌入在 Noda Time 中的 CLDR 数据进行转换。我已经在这篇文章中记录了如何做到这一点: 如何在 Windows 和 IANA 时区之间进行转换?

但更好的解决方案是一起避免 Windows 区域。您可以使用我在这篇文章中描述的技术填充 IANA/Olson id 列表: 我应该如何从 Noda Time 填充 IANA/Olson 时区列表?

更好的是,您可以将下拉列表替换为显示世界地图的控件(内联或模式),以便您的用户可以轻松选择他们的时区。我见过的最好的控制是这个,但也有一些其他的。

如果您可以在 IANA/Olson 区域严格处理,则无需转换。您可以放弃 WindowsTimeZoneInfo对象而只使用 Noda Time。如果你愿意,你可以只替换你的时区转换函数,其余的保持不变。或者,您可以全力以赴,用 Noda Time 类型替换您的所有DateTime和使用。DateTimeOffset由你决定。

于 2013-07-10T16:02:06.093 回答