微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

javascript – 将Windows时区转换为moment.js时区?

我们在ASP.NET中有一个应用程序,它以 Windows格式存储所有用户时区数据(通过TimeZoneInfo.Id).

我们还使用moment.js和moment.js TimeZone库将UTC数据转换为客户端的用户数据.这是一个复杂的AngularJs应用程序,需要在客户端进行时区转换.

到目前为止,我们使用NodaTime .NET库将Windows时区ID转换为Moment.js时区ID.它适用于大多数常见时区.
但我们需要使这种转换100%兼容.

目前看来,没有可靠的方法将Windows时区ID映射到IANA时区数据.存在很多差异.

我相信现代JS应用经常处理时区.有时需要在服务器端(C#)和客户端(JS)上完全转换TZ.

有没有办法严格地将.NET TimeZoneInfo映射/转换为Moment.js时区对象?

解决方法

TL; DR:

>继续在服务器端使用Noda Time
>选择是否使用BCL数据或IANA数据;我个人推荐IANA,但这是你的电话. (除此之外,IANA数据的版本更清晰.)
>使用Noda Time生成moment.js数据,以便准确了解客户端将使用的内容,并且它与您在服务器上执行的操作一致
>制定战略,了解数据发生变化时的情况

细节:

And sometimes need to convert TZ exactly on server-side (C#) and client-side (JS).

您需要在两侧获得完全相同的时区数据,并在两侧获得等效的实现.这有问题,因为:

> IANA时区数据定期更新(例如,您需要能够说“使用数据2015a”)
> Windows时区数据会定期更新
>我不想打赌IANA规则的每个实施都是完全相同的,即使它们应该是
>我知道TimeZoneInfo实现随着时间的推移而发生了变化,部分是为了删除一些odd bugs,部分删除到了include more data.(.NET 4.6理解时区的概念在历史上改变了它的标准偏移;早期版本没有)

使用Noda Time,您可以非常轻松地将BCL或IANA时区数据转换为moment.js格式 – 并且比Evgenyt的代码更可靠地执行此操作,因为TimeZoneInfo不允许您请求转换. (由于TimeZoneInfo本身的错误,有一些小口袋,偏移量可以改变几个小时 – 他们不应该,但如果你想要完全匹配TimeZoneInfo行为,你需要能够找到所有这些 – Evgenyt的代码并不总能发现那些.)即使Noda Time没有完全反映TimeZoneInfo,它也应该与自己一致.

moment.js格式看起来很简单,所以只要你不介意将数据发送到客户端,这绝对是一个选择.您需要考虑数据更改时要执行的操作:

>你如何在服务器上拿起它?
>您如何使用旧数据临时处理客户?

如果确切的一致性对您来说非常重要,您可能希望将时区数据发送到具有时区数据版本的客户端…然后客户端可以在发布数据时将其呈现给服务器. (当然,我假设它正在这样做.)然后服务器可以使用该版本,或者拒绝客户端的请求,并说有更新的数据.

这里有一些示例代码可以将Noda时区数据转换为moment.js – 它看起来对我很好,但我没有做太多.它与momentjs.com中的文档相匹配…请注意,偏移量必须反转,因为由于某种原因,moment.js决定对UTC后面的时区使用正偏移量.

using System;
using System.Linq;

using NodaTime;
using Newtonsoft.Json;

class Test
{
    static void Main(string[] args)
    {
        Console.WriteLine(GenerateMomentJsZoneData("Europe/London",2010,2020));
    }

    static string GenerateMomentJsZoneData(string tzdbId,int fromYear,int toYear)
    {
        var intervals = DateTimeZoneProviders
            .Tzdb[tzdbId]
            .GetZoneIntervals(Instant.FromUtc(fromYear,1,0),Instant.FromUtc(toYear + 1,0))
            .ToList();

        var abbrs = intervals.Select(interval => interval.Name);
        var untils = intervals.Select(interval => interval.End.Ticks / NodaConstants.TicksPerMillisecond);
        var offsets = intervals.Select(interval => -interval.WallOffset.Ticks / NodaConstants.TicksPerMinute);
        var result = new { name = tzdbId,abbrs,untils,offsets };
        return JsonConvert.SerializeObject(result);
    }
}

原文地址:https://www.jb51.cc/js/158244.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐