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

时间:2015-07-24 11:36:59

标签: c# asp.net sql-server timezone dst

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

首先让我解释一下应用程序的流程,我正在为采购订单存储一个对象。所以它里面有datetime字段。

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

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

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

比较偏移时,我得到一个TimeZoneInfo对象(例如)“(UTC-08:00)Baja California”,“(UTC +05:30)Chennai,Kolkata”

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

通过上述流程,该应用程序适用于某些时区。

问题是,如果我将客户端计算机的时区更改为(UTC -8:00),客户端计算机会将时区名称显示为“(UTC-08:00)太平洋时间(美国和加拿大)”,但在应用程序中,时区不同于它显示为“(UTC-08:00)Baja California”的客户端系统。

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

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

我的问题是:

  • 当我们将UTC转换为本地时,TimeZoneInfo类是否可以根据调整规则自动工作?

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

  • .Net中还有其他类可以与windows时区同步吗?

1 个答案:

答案 0 :(得分:3)

您应该了解的一些事项:

  1. 时区与时区偏移量不同。人们不能只拿数字-8并假设时区应该是太平洋时间。

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

  3. DisplayName的{​​{1}}属性中的偏移量仅为标准偏移量。它们与TimeZoneInfo属性匹配。它们不会更改以反映当前偏移量。

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

    • 使用BaseOffset类的getTimezoneOffset函数,该函数应返回调用日期的偏移量。例如,Date为您提供当前偏移量。使用这种方法,您还应该意识到a bug in the ES5 spec可能导致在较旧日期调用时有时会返回错误的偏移量。

    • 使用jsTimezoneDetect之类的库,它会多次调用new Date().getTimezoneOffset()来尝试猜测IANA时区标识符。当向用户呈现时区列表时,猜测适合于设置默认时区。这只是猜测,可能是错的。如果您想在.NET的后端使用它,那么您需要Noda Time,因为getTimezoneOffset目前不支持IANA时区。 (如果需要,您可以选择convert到Windows时区。

    • 一些较新的浏览器支持ECMAScript Internationalization API,它有一个可选的实现函数来返回时区。 可能在某些浏览器中工作,但无法保证在任何地方返回有效结果。

      TimeZoneInfo

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

  5. 你说:

      

    问题是,如果我将客户端计算机的时区更改为(UTC -8:00),客户端计算机会将时区名称显示为"(UTC-08:00)太平洋时间(美国和加拿大) )"但在应用程序中,时区与它显示的客户端系统不同(#UTC; 08:00)Baja California"。

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

  6. 回答您的具体问题:

    •   

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

      是的,它可以。 Intl.DateTimeFormat().resolvedOptions().timeZone没有任何问题,这完全取决于您如何使用它。您可能选择了错误的时区。

    •   

      我们是否必须使用方法TimeZoneInfo检测特定日期时间的DST并进行转换?

      不,你不应该只是为了从UTC转换到特定的时区。 TimeZoneInfoObject.IsDaylightSavingTime(DateTime)函数将为您处理。

    •   

      .Net中还有其他类可以与windows时区同步吗?

      ConvertTimeFromUtc是.NET Framework中唯一内置的。 Noda Time是适用于Windows时区或IANA时区的绝佳选择。

    最后,我将重新讨论Jon在评论中所说的内容。如果您所做的只是向最终用户显示特定时刻,则根本忘记时区检测或在服务器上使用本地时间。只需将UTC时间发送到客户端,并使用JavaScript TimeZoneInfo对象上的UTC函数,或使用moment.js之类的库。要么可以在UTC和本地工作,并且可以在它们之间进行转换。例如(使用moment.js):

    Date