我正在做一个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日期时间(存储在DB中)转换为客户端的时区。
问题是,如果当我将客户端机器的时区更改为(UTC -8:00)时,客户端机器显示的时区名称为"(UTC-08:00)太平洋时间(US &加拿大),但在应用程序中,时区与客户端系统不同,它显示为"(UTC-08:00) Baja California"。
重要的是,当我将UTC转换为本地时,DST变化不会反映出来。TimeZoneInfo.ConvertTimeFromUtc(DateTime, clientTimezone);
注意:我没有在数据库或任何地方存储客户端的时区信息。因此,每次如果用户进入应用程序,应用程序将识别时区,并根据它做出反应。
我的问题是:当我们从UTC转换为Local时,TimeZoneInfo类是否可以根据调整规则自动工作?
我们是否必须使用
TimeZoneInfoObject.IsDaylightSavingTime(DateTime)
方法检测特定日期时间的DST并进行转换?在。net中是否有其他类可以与windows时区同步?
你应该明白的几件事:
-
时区与时区偏移量不同。我们不能只看到数字-8就认为时区应该是太平洋时间。
-
偏移量可以在单个时区内更改。例如,太平洋时间通常使用-8,但在夏令时生效时切换到-7。
-
TimeZoneInfo
的DisplayName
属性中的偏移量只是标准偏移量。它们与BaseOffset
属性匹配。它们不会改变以反映当前偏移量。 -
JavaScript中的时区检测是不完善的。只有三种方法:
-
使用
Date
类的getTimezoneOffset
函数,它应该返回调用日期的偏移量。例如,new Date().getTimezoneOffset()
给出当前偏移量。使用这种方法,您还应该意识到ES5规范中有一个错误,可能导致在旧日期调用时返回错误的偏移量。 -
使用诸如jsTimezoneDetect之类的库,它对
getTimezoneOffset
进行多次调用以尝试猜测IANA时区标识符。当向用户显示时区列表时,这种猜测适用于设置默认时区。这只是一个猜测,而且可能是错误的。如果你想在后端使用。net,你需要野田时间,因为TimeZoneInfo
目前不支持IANA时区。(如果需要,可以选择转换为Windows时区)。 -
一些较新的浏览器支持ECMAScript国际化API,它有一个可选的实现函数来返回时区。可以在某些浏览器中工作,但不能保证在任何地方都返回有效的结果。
Intl.DateTimeFormat().resolvedOptions().timeZone
同样,在后端需要Noda Time。
你说 -
:
问题是,如果当我将客户端机器的时区更改为(UTC -8:00)时,客户端机器显示的时区名称为"(UTC-08:00)太平洋时间(US &加拿大),但在应用程序中,时区与客户端系统不同,它显示为"(UTC-08:00) Baja California"。
这可能与您如何在应用程序代码中选择时区有关。在我看来,您正在扫描服务器时区列表,并选择第一个符合某些标准的时区。由于这两个时区具有相同的基本偏移量,您可能只是选错了一个,而且您不应该这样做。但是因为你没有展示那部分代码,所以我也帮不上什么忙。
回答您的具体问题:
-
当我们从UTC转换为Local时,TimeZoneInfo类是否可以根据调整规则自动工作?
是的,它可以。
TimeZoneInfo
没有任何问题,关键是你如何使用它。您可能选择了错误的时区。 -
我们是否必须使用
TimeZoneInfoObject.IsDaylightSavingTime(DateTime)
方法检测特定日期时间的DST并进行转换?不,您不应该只是为了从UTC转换到特定的时区而这样做。
ConvertTimeFromUtc
函数将为您处理。 -
在。net中还有其他类可以与windows时区同步吗?
TimeZoneInfo
是唯一内置于。net框架中的。Noda Time是一个很好的选择,可以在Windows时区或IANA时区工作。
最后,我将在评论中重申Jon所说的话。如果您所做的只是向终端用户显示某个特定时刻的时间,那么完全不要考虑时区检测或使用服务器上的本地时间。只需将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)