我们在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:
细节:
有时需要完全在服务器端(C#)和客户端(JS)上转换TZ。
你需要得到确切两侧同一时区的数据和等效实施在两侧。这有问题,因为:
TimeZoneInfo
实施,随着时间的推移发生变化,部分是为了去除一些奇怪的错误,部分原因包括更多的数据。(.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, 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);
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句