首页 文章

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

提问于
浏览
2

我正在开发一个支持时区的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 对象,我'm converting the UTC datetime (which is stored in DB) to the client'的时区 .

通过上面的流程,该应用程序适用于某些时区 .

问题是,如果我将客户端计算机的时区更改为(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 回答

  • 3

    你应该了解的一些事情:

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

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

    • TimeZoneInfoDisplayName 属性中的偏移量仅为标准偏移量 . 它们与 BaseOffset 属性匹配 . 它们不会改变以反映当前的偏移量 .

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

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

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

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

    Intl.DateTimeFormat().resolvedOptions().timeZone

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

    • 你说:

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

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

    回答您的具体问题:

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

    是的,它可以 . 没有错与 TimeZoneInfo ,它's all about how you'重新使用它 . 您可能正在选择错误的时区 .

    • 我们是否必须使用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)
    

相关问题