gpt4 book ai didi

javascript - 如何使用时刻时区与 C# TimeZoneInfo 进行映射?

转载 作者:行者123 更新时间:2023-12-01 01:23:27 28 4
gpt4 key购买 nike

我需要制造在用户选择的时区中工作的错觉。服务器和客户端代码坚持 JavaScript 日期的问题。因此,为了达到要求,我手动将 utc 映射到客户端的日期:

dateToServer(date) {
const momentDate = moment(date);
let serverDate = null;
if (momentDate.isValid() && date) {
const browserUtcOffset = momentDate.utcOffset();
serverDate = momentDate
.utc()
.subtract(this.clientTimeZoneOffset, 'minutes')
.add(browserUtcOffset, 'minutes')
.toDate();
}
return serverDate;
}


dateToClient(date) {
const momentDate = moment(date);
let uiDate = null;
if (momentDate.isValid() && date) {
const browserUtcOffset = momentDate.utcOffset();
uiDate = momentDate
.utc()
.subtract(browserUtcOffset, 'minutes')
.add(this.clientTimeZoneOffset, 'minutes')
.toDate();
}
return uiDate;
}

我正在添加/减去 browserUtcOffset,因为当日期在服务器和客户端之间传输时,浏览器会自动添加/减去。

它运行良好,但该解决方案缺少对 DST 的处理。我想检查该日期是否启用 DST,然后根据需要添加 DST 偏移量。

这里是可以执行此操作的 C# 代码:

        string timeZone = "Central Standard Time";
TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(timeZone);
DateTime date = new DateTime(2011, 3, 14);
Console.WriteLine(timeZoneInfo.BaseUtcOffset.TotalMinutes); // -360
Console.WriteLine(timeZoneInfo.GetUtcOffset(date).TotalMinutes); // -300
Console.WriteLine(timeZoneInfo.IsDaylightSavingTime(date)); // true
Console.WriteLine(timeZoneInfo.DaylightName);
Console.WriteLine(timeZoneInfo.SupportsDaylightSavingTime);

我在 momentjs 中找到了 isDST,当我将 Windows 本地时区设置为 CST 并检查 moment([2011, 2, 14]).isDST(); 在浏览器控制台中我看到了 true。如何查看 isDST 取决于浏览器本地时间。

下一步尝试使用 moment-timezone 来做一些事情,就像我在 C# 中所做的那样。不幸的是我不明白如何实现这一点。作为起点的第一个问题是:UTC 时间基准偏移量(C# 示例中的-360)时区名称:中部标准时间 ,但时刻时区中的时区不同。

moment.tz.names().map(name => moment.tz.zone(name)).filter(zone => zone.abbrs.find(abbr => abbr === 'CST' ) != null) 此代码返回 68 个时区。 enter image description here

为什么他们每个人都有很多缩写?直到什么意思?我只想检查所选时区的 UTC 时间(即“中部标准时间”)是否启用夏令时。再看一次 C# 示例:)

        string timeZone = "Central Standard Time";
TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(timeZone);
DateTime date = new DateTime(2011, 3, 14);
Console.WriteLine(timeZoneInfo.BaseUtcOffset.TotalMinutes); //-360
Console.WriteLine(timeZoneInfo.GetUtcOffset(date).TotalMinutes); //-300
Console.WriteLine(timeZoneInfo.IsDaylightSavingTime(date)); //true, I have checked is daylightsavingtime for the date
Console.WriteLine(timeZoneInfo.DaylightName);
Console.WriteLine(timeZoneInfo.SupportsDaylightSavingTime);

该应用程序是在 angularjs 1.6.3 上编写的。

最佳答案

一些事情:

  • JavaScript 中的 Date 对象跟踪基于 UTC 的特定时间点。您可以通过调用 .valueOf().getTime() 来查看该时间戳。只有某些函数和构造函数参数适用于本地时区(例如 .toString())。该本地时区在调用该函数时应用。无法替换不同的时区(传递给 toLocaleString 的选项对象除外)。因此,Date 对象无法从一个时区转换为另一个时区。因为您的两个函数都接受 Date 对象并返回 Date 对象,所以您在中间所做的就是选择不同的时间点。在使用 Moment 的 addsubtract 方法的函数中也可以看到这一点。他们操纵所表示的时间点 - 他们不改变时区。

  • 通过传递 this.clientTimeZoneOffset,您似乎将时区与时区偏移量混为一谈。这些是不同的概念,因为时区可能会经历多个不同的偏移量,这是由于夏令时,也是由于历史上发生过的标准时间的变化。另请参阅 the timezone tag wiki 中的“时区!= 偏移” 。仅传递客户端的偏移量是没有用的,因为该偏移量仅适用于单个时间点。您不能将其用于时区转换,因为它不会告诉您有关其他时间点使用哪些偏移量的任何信息。

  • 而是传递时区标识符。在 .NET 中的 Windows 上,这些时间看起来像“中央标准时间”(尽管名称不同,但仍代表标准时间和夏令时),而在 JavaScript 和大多数其他操作系统中,则使用 IANA 时区名称。它们看起来像“美国/芝加哥”。 timezone tag wiki 中也对此进行了介绍。 .

  • 如果您的 .NET 代码使用 Windows 标识符,您可以使用我的 TimeZoneConverter库从 Windows 转换为 IANA,然后将该字符串作为时区发送到浏览器。

  • 使用 Moment-Timezone,您可以简单地检查 DST,如下所示:

    moment.tz([2011, 2, 14], 'America/Chicago').isDST()

    同样,您应该使用 IANA time zone IDs ,如果您在服务器端使用 Windows 时区,TimeZoneConverter 可以提供它们。

  • 可以考虑使用 Noda Time在服务器端,及其 TZDB 时区提供商。这样您就可以在两侧使用 IANA 时区。在 Linux 或 Mac OSX 上的 .NET Core 上运行时,TimeZoneInfo 也是如此。

  • 当您使用 CST 搜索缩写词时,您会看到如此多的条目,原因是时区缩写词不明确。您可能指的是美国中部标准时间,但也可能指的是古巴标准时间或中国标准时间,或其他使用该缩写的地方。

  • 关于 untils 数组,您通常不需要关心它。它是 Moment-Timezone 用来选择正确时间点以选择时区偏移和缩写的内部数据的一部分。

  • 你最后说的有些不同:

    All I want to check if UTC time in the selected timezone, which is "Central Standard Time", the daylight saving day active.

    我之前给出的示例假设您从该时区的本地时间开始。如果您从 UTC 时间开始,则如下所示:

    moment.utc([2011, 2, 14]).tz('America/Chicago').isDST()

    当然,您可以在我传递数组的地方传递各种其他支持的输入。 Moment docs可以帮助您选择可用的选项。

关于javascript - 如何使用时刻时区与 C# TimeZoneInfo 进行映射?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54039223/

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