关于javascript:moment.js,时区和夏令时

moment.js, timezones and daylight savings

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

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

在客户机上,我将这些字符串值转换为相应的基于UTC的时刻,就像这样

1
var fooUtc = new moment.utc(serverDateTimeString)

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

1
2
3
4
5
6
7
8
9
{
    id:"Central Standard Time",
    label:"(UTC-06:00) Central Time (US & Canada)",
    observesDaylightSavings: true,
    baseUtcOffset: {
        asHours: -6,
        asMinutes: -360,
        asText:"-06:00"
}

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

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

但是,结果不考虑日光节约,因为来自.NET的时区数据不区分DST和非DST偏移。

有没有一种方法可以使用moment.js或新的moment时区位?我认为如果我可以将标准的UTC偏移量名称(例如:"中央标准时间")映射到给定时区的olson db标识符(例如:"美国/芝加哥")是可能的,但是如果有更简单的方法,请告诉我。


您应该在.NET端使用noda time,在客户端使用moment timezone,并传递IANA/olson时区ID。

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

但更好的解决办法是避免所有的窗口区域在一起。您可以使用我在本文中描述的技术来填充IANA/OLSON ID列表:如何从NODA时间填充IANA/OLSON时区列表?

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

如果你能在IANA/OLSON区域严格交易,那么就不需要转换。你可以放弃windowsTimeZoneInfo对象,只使用noda时间。如果您愿意,您可以只替换时区转换函数,其余的保持不变。或者,您可以全力以赴,用noda时间类型替换所有的DateTimeDateTimeOffset。这取决于你。