繁体   English   中英

从UTC转换为本地时,夏令时在TimeZoneInfo中不起作用

[英]Daylight Saving Time not working in TimeZoneInfo, when converting from UTC to Local

我正在开发一个支持时区的ASP.NET/C#应用程序。

首先让我解释一下应用程序的流程,我要存储一个采购订单对象。 因此它具有datetime字段。

我将该datetime作为UTC存储在数据库中,并将其绑定到网格中(根据客户端的时区)。

在第一页的Page_Init方法中,我使用了一个javascript代码,它将检测客户端的时区,并返回适当的偏移量。

Page_Load方法中,我获取了该javascript返回值(偏移量)并将其与TimeZoneInfo.GetSystemTimeZones()中每个区域的偏移量进行比较。

比较偏移量时,我得到一个TimeZoneInfo对象(例如)“(UTC-08:00)下加利福尼亚州”,“(UTC +05:30)加尔各答金奈”

使用特定的TimeZoneInfo对象,我将UTC日期时间(存储在数据库中)转换为客户端的时区。

如上述流程所示,该应用程序在某些时区可以正常工作。

问题是,如果当我将客户端计算机的时区更改为(UTC -8:00)时,客户端计算机将时区名称显示为“(UTC-08:00)Pacific Time(美国和加拿大)”,但是在应用中是时区与显示为“(UTC-08:00)下加利福尼亚州”的客户端系统不同。

重要的是,当我将UTC转换为Local时,DST的更改未反映出来。 TimeZoneInfo.ConvertTimeFromUtc(DateTime, clientTimezone);

注意:我不会在数据库中或任何地方存储客户端的时区信息。 因此,每次用户进入应用程序时,应用程序都会识别时区,并会根据时区做出反应。

我的问题是:

  • 从UTC转换为Local时,TimeZoneInfo类是否可以根据调整规则自动工作?

  • 我们是否必须使用方法TimeZoneInfoObject.IsDaylightSavingTime(DateTime)检测特定日期时间的DST并进行转换?

  • .Net中是否还有其他可以与Windows时区同步的类?

您应该了解以下几点:

  1. 时区与时区偏移量不同。 一个人不能只取数字-8并假定时区应为太平洋时间。

  2. 偏移量可以在单个时区内更改。 例如,太平洋时间通常使用-8,但在实行夏令时时会切换为-7。

  3. TimeZoneInfoDisplayName属性中的偏移量仅是标准偏移量。 它们与BaseOffset属性匹配。 它们不会更改以反映当前偏移。

  4. JavaScript中的时区检测不完善。 只有三种方法:

    • 使用Date类的getTimezoneOffset函数,该函数应返回您调用它的日期的偏移量。 例如, new Date().getTimezoneOffset()为您提供当前偏移量。 使用这种方法,您还应该知道ES5规范中存在一个错误,该错误可能导致在较旧的日期上调用时有时会返回错误的偏移量。

    • 使用诸如jsTimezoneDetect之类的库,该库对getTimezoneOffset进行了多次调用,以尝试猜测IANA时区标识符。 当将时区列表显示给用户时,此猜测适合设置默认时区。 这只是一个猜测,可能是错误的。 如果要在.NET的后端使用它,则需要Noda Time ,因为TimeZoneInfo当前不支持IANA时区。 (如果需要,可以选择转换为Windows时区)。

    • 一些较新的浏览器支持ECMAScript国际化API ,该API具有一个可选实现的函数来返回时区。 可能在某些浏览器中有效,但不能保证在任何地方都返回有效结果。

      Intl.DateTimeFormat().resolvedOptions().timeZone

      同样,您将需要在后端使用Noda Time。

  5. 你说:

    问题是,如果当我将客户端计算机的时区更改为(UTC -8:00)时,客户端计算机将时区名称显示为“(UTC-08:00)Pacific Time(美国和加拿大)”,但是在应用中是时区与显示为“(UTC-08:00)下加利福尼亚州”的客户端系统不同。

    这可能与您在应用程序代码中选择时区的方式有关。 在我看来,您正在扫描服务器时区列表,然后选择第一个符合某些条件的时区。 由于这两个时区都具有相同的基本偏移,因此您可能只是选择了错误的偏移,因此无论如何都不应这样做。 但是,由于您没有显示代码的那部分,因此我在这里没有太大帮助。

要回答您的特定问题:

  • 从UTC转换为Local时,TimeZoneInfo类是否可以根据调整规则自动工作?

    是的,它可以。 TimeZoneInfo没有错,这与您的使用方式有关。 您可能选择了错误的时区。

  • 我们是否必须使用方法TimeZoneInfoObject.IsDaylightSavingTime(DateTime)检测特定日期时间的DST并进行转换?

    不,您不必仅将UTC转换为特定时区即可。 ConvertTimeFromUtc函数将为您处理该问题。

  • .Net中是否还有其他可以与Windows时区同步的类?

    TimeZoneInfo是.NET Framework中唯一内置的。 Noda Time是可以与Windows时区或IANA时区一起使用的绝佳选择。

最后,我将重申乔恩的评论。 如果您要做的只是向最终用户显示特定的时间点,那么根本就不必进行时区检测或完全在服务器上使用本地时间。 只需将UTC时间发送给客户端,并在JavaScript Date对象上使用UTC函数,或使用诸如moment.js之类的库即可 两者都可以在UTC和本地中工作,并且可以在它们之间进行转换。 例如(使用moment.js):

var valueFromServer = "2015-07-26T12:00:00Z";     // the Z means UTC
var localTime = moment(valueFromServer).format(); // "2015-07-26T05:00:00-07:00"  (Pacific)

暂无
暂无

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

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