简体   繁体   English

moment.js、时区和夏令时

[英]moment.js, timezones and daylight savings

I return a list of UTC dates/times from a .Net service, formatted like so:我从 .Net 服务返回 UTC 日期/时间列表,格式如下:

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

On the client, I convert each of these string values into a corresponding UTC-based moment, like so在客户端,我将这些字符串值中的每一个转换为相应的基于 UTC 的时刻,就像这样

var fooUtc = new moment.utc(serverDateTimeString)

On the page, there is a droop-down containing a list of time-zones that the user can change.在页面上,有一个下拉列表,其中包含用户可以更改的时区列表。 These are tied to a collection of time-zone objects like the following:这些与时区对象的集合相关联,如下所示:

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

I then display each moment passing in the selected time-zone offset, like so:然后,我显示通过所选时区偏移的每个时刻,如下所示:

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

However, the result does not take into account daylight savings, as the timezone data coming from .Net does not differentiate between dst and non dst offsets.但是,结果没有考虑夏令时,因为来自 .Net 的时区数据不区分 dst 和非 dst 偏移量。

Is there a way to make this work with moment.js or the new moment-timezone bits?有没有办法使用 moment.js 或新的 moment-timezone 位来完成这项工作? I think it could be possible if I could map the standard UTC offset names (ex: "Central Standard Time") to a given timezone's Olson DB identifier (ex: "America/Chicago"), but if there is an easier way, please let me know.我认为如果我可以将标准 UTC 偏移名称(例如:“中部标准时间”)映射到给定时区的Olson DB 标识符(例如:“America/Chicago”),这是可能的,但如果有更简单的方法,请让我知道。

You should explore using Noda Time on the .Net side, and moment-timezone on the client, passing the IANA/Olson time zone id. 您应该在.Net端使用Noda Time ,在客户端上使用moment-timezone ,并传递IANA / Olson时区ID。

If you want to stick to the Windows time zone ids in your drop-down list, then you can do conversions with the CLDR data embedded in Noda Time. 如果要保留下拉列表中的Windows时区ID,则可以使用Noda Time中嵌入的CLDR数据进行转换。 I have documented how to do it in this post: How to translate between Windows and IANA time zones? 我在这篇文章中记录了如何做到这一点: 如何在Windows和IANA时区之间转换?

But the better solution would be to avoid the Windows zones all together. 但是更好的解决方案是避免一起使用Windows区域。 You can populate a list of IANA/Olson ids using the technique I describe in this post: How should I populate a list of IANA / Olson time zones from Noda Time? 您可以使用我在本文中介绍的技术填充IANA / Olson ID列表: 我应该如何从Noda Time填充IANA / Olson时区列表?

Better yet, you can replace your drop-down list with a control (inline or modal) that displays a map of the world, so your users can easily select their time zone. 更好的是,您可以使用显示世界地图的控件(内联或模式)替换下拉列表,以便您的用户可以轻松选择他们的时区。 The best control for this that I have seen is this one , but there are a few others out there also. 我所见过的对此的最佳控制方法是此方法 ,但也有一些其他方法。

If you can deal strictly in IANA/Olson zones, then there's no need for conversion. 如果您可以严格在IANA / Olson地区进行交易,则无需进行转换。 You can give up the Windows TimeZoneInfo object and just use Noda Time instead. 您可以放弃Windows TimeZoneInfo对象,而仅使用Noda Time。 If you want, you can replace just your time zone conversion functions and leave the rest intact. 如果需要,您可以仅替换您的时区转换功能,其余部分保持不变。 Or, you could go all-out and replace all of your DateTime and DateTimeOffset uses with Noda Time types. 或者,您可以全力以赴,用Noda Time类型替换所有的DateTimeDateTimeOffset使用。 It's up to you. 由你决定。

moment(date).add(moment().utcOffset(), 'm').format('DD-MM-YYYY - h:mm:ss');

This works perfectly fine for me.这对我来说非常好。 It converts utc time to local time by adding/subtracting utc offset time while catering to DST它通过在满足 DST 的同时添加/减去 utc 偏移时间来将 utc 时间转换为本地时间

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM