gpt4 book ai didi

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

转载 作者:数据小太阳 更新时间:2023-10-29 04:33:33 25 4
gpt4 key购买 nike

我们在 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 时区对象?

最佳答案

长话短说:

  • 继续在服务器端使用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 没有完全反射(reflect) 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, 1, 0, 0),
Instant.FromUtc(toYear + 1, 1, 1, 0, 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);
}
}

关于javascript - 将 Windows 时区转换为 moment.js 时区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28088984/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com