从 UTC 转换为本地时,夏令时在 TimeZoneInfo 中不起作用
Daylight Saving Time not working in TimeZoneInfo, when converting from UTC to Local
我正在开发一个支持时区的 ASP.NET/C# 应用程序。
首先让我解释一下应用程序的流程,我正在存储采购订单的对象。所以它里面有 datetime
字段。
我将 datetime
作为 UTC 存储在数据库中,并将其绑定到网格中(根据客户的时区)。
在第一页的 Page_Init
方法中,我使用了 javascript 代码来检测客户端的时区和 return 适当的偏移量。
在 Page_Load
方法中,我得到 javascript return 值(偏移量)并将其与 TimeZoneInfo.GetSystemTimeZones()
中每个区域的偏移量进行比较。
比较偏移量时,我得到一个 TimeZoneInfo
对象(例如)“(UTC-08:00) Baja California”、“(UTC +05:30) Chennai,Kolkata”。 =19=]
使用那个特定的 TimeZoneInfo
对象,我将 UTC 日期时间(存储在数据库中)转换为客户端的时区。
按照上述流程,应用程序在 一些 时区工作正常。
问题是,如果当我将客户端计算机的时区更改为 (UTC -8:00) 时,客户端计算机将时区名称显示为“(UTC-08:00) 太平洋时间(美国和加拿大)”但在应用程序中,时区与客户端系统不同,它显示为“(UTC-08:00) Baja California”。
重要的是,当我将 UTC 转换为本地时,DST 更改没有反映出来。 TimeZoneInfo.ConvertTimeFromUtc(DateTime, clientTimezone);
注意:我没有将客户端的时区信息存储在数据库或任何地方。因此,每次用户进入应用程序时,应用程序都会识别时区并根据时区做出反应。
我的问题是:
当我们从UTC转换为Local时,TimeZoneInfo class是否可以根据调整规则自动工作?
我们是否必须使用方法 TimeZoneInfoObject.IsDaylightSavingTime(DateTime)
检测特定日期时间的 DST 并进行转换?
.Net 中是否有任何其他 class 可以与 windows 时区同步?
你应该明白的几件事:
时区与时区偏移不同。不能只取数字 -8 并假设时区应该是太平洋时间。
偏移量可以在单个时区内更改。例如,太平洋时间通常使用-8,但在夏令时生效时切换为-7。
TimeZoneInfo
DisplayName
属性中的偏移量只是标准偏移量。它们与 BaseOffset
属性 匹配。它们不会更改以反映 当前 偏移量。
JavaScript 中的时区检测不完善。只有三种方法:
使用 Date
class 的 getTimezoneOffset
函数,这应该 return 您调用它的日期的偏移量。例如 new Date().getTimezoneOffset()
为您提供 current 偏移量。使用这种方法,您还应该意识到 a bug in the ES5 spec 可能会导致错误的偏移量有时会在较旧的日期调用时被 returned。
如果需要,使用 jsTimezoneDetect, which makes several calls to the getTimezoneOffset
to attempt to guess at an IANA time zone identifier. The guess is suitable to set a default time zone when a list of time zones is presented to the user. It is just a guess, and could be wrong. If you want to use it on the back end with .NET, you'll need Noda Time, since TimeZoneInfo
doesn't currently support IANA time zones. (You can optionally convert 等库到 Windows 时区)。
一些较新的浏览器支持 ECMAScript Internationalization API,它有一个可选的 return 时区功能。它 可能 在某些浏览器中工作,但不能保证 return 在任何地方都是有效的结果。
Intl.DateTimeFormat().resolvedOptions().timeZone
同样,后端需要 Noda Time。
你说:
The problem is, if when I change timezone of client machine to (UTC -8:00), the client machine shows the timezone name as "(UTC-08:00) Pacific Time (US & Canada)" but in application the timezone differs from the client system it shows as "(UTC-08:00) Baja California".
这可能与您在应用程序代码中选择时区的方式有关。在我看来,您正在扫描服务器时区列表并选择第一个符合某些条件的时区。由于这两个时区具有相同的基准偏移量,您可能只是选择了错误的时区,无论如何都不应该这样做。但是因为你没有展示那部分代码,所以我帮不了你太多。
回答您的具体问题:
Whether the TimeZoneInfo class can work automatically work according to the adjusment rule, when we convert from UTC to Local?
是的,可以。 TimeZoneInfo
没有错,关键在于你如何使用它。您可能选择了错误的时区。
Do we have to detect the DST for particular datetime using the method TimeZoneInfoObject.IsDaylightSavingTime(DateTime)
and do conversion?
不,您不必为了从 UTC 转换为特定时区而这样做。 ConvertTimeFromUtc
函数将为您处理。
Is there any other classes in .Net which can sync with windows timezones?
TimeZoneInfo
是 .NET Framework 中唯一内置的。 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)
我正在开发一个支持时区的 ASP.NET/C# 应用程序。
首先让我解释一下应用程序的流程,我正在存储采购订单的对象。所以它里面有 datetime
字段。
我将 datetime
作为 UTC 存储在数据库中,并将其绑定到网格中(根据客户的时区)。
在第一页的 Page_Init
方法中,我使用了 javascript 代码来检测客户端的时区和 return 适当的偏移量。
在 Page_Load
方法中,我得到 javascript return 值(偏移量)并将其与 TimeZoneInfo.GetSystemTimeZones()
中每个区域的偏移量进行比较。
比较偏移量时,我得到一个 TimeZoneInfo
对象(例如)“(UTC-08:00) Baja California”、“(UTC +05:30) Chennai,Kolkata”。 =19=]
使用那个特定的 TimeZoneInfo
对象,我将 UTC 日期时间(存储在数据库中)转换为客户端的时区。
按照上述流程,应用程序在 一些 时区工作正常。
问题是,如果当我将客户端计算机的时区更改为 (UTC -8:00) 时,客户端计算机将时区名称显示为“(UTC-08:00) 太平洋时间(美国和加拿大)”但在应用程序中,时区与客户端系统不同,它显示为“(UTC-08:00) Baja California”。
重要的是,当我将 UTC 转换为本地时,DST 更改没有反映出来。 TimeZoneInfo.ConvertTimeFromUtc(DateTime, clientTimezone);
注意:我没有将客户端的时区信息存储在数据库或任何地方。因此,每次用户进入应用程序时,应用程序都会识别时区并根据时区做出反应。
我的问题是:
当我们从UTC转换为Local时,TimeZoneInfo class是否可以根据调整规则自动工作?
我们是否必须使用方法
TimeZoneInfoObject.IsDaylightSavingTime(DateTime)
检测特定日期时间的 DST 并进行转换?.Net 中是否有任何其他 class 可以与 windows 时区同步?
你应该明白的几件事:
时区与时区偏移不同。不能只取数字 -8 并假设时区应该是太平洋时间。
偏移量可以在单个时区内更改。例如,太平洋时间通常使用-8,但在夏令时生效时切换为-7。
TimeZoneInfo
DisplayName
属性中的偏移量只是标准偏移量。它们与BaseOffset
属性 匹配。它们不会更改以反映 当前 偏移量。JavaScript 中的时区检测不完善。只有三种方法:
使用
Date
class 的getTimezoneOffset
函数,这应该 return 您调用它的日期的偏移量。例如new Date().getTimezoneOffset()
为您提供 current 偏移量。使用这种方法,您还应该意识到 a bug in the ES5 spec 可能会导致错误的偏移量有时会在较旧的日期调用时被 returned。如果需要,使用 jsTimezoneDetect, which makes several calls to the
getTimezoneOffset
to attempt to guess at an IANA time zone identifier. The guess is suitable to set a default time zone when a list of time zones is presented to the user. It is just a guess, and could be wrong. If you want to use it on the back end with .NET, you'll need Noda Time, sinceTimeZoneInfo
doesn't currently support IANA time zones. (You can optionally convert 等库到 Windows 时区)。一些较新的浏览器支持 ECMAScript Internationalization API,它有一个可选的 return 时区功能。它 可能 在某些浏览器中工作,但不能保证 return 在任何地方都是有效的结果。
Intl.DateTimeFormat().resolvedOptions().timeZone
同样,后端需要 Noda Time。
你说:
The problem is, if when I change timezone of client machine to (UTC -8:00), the client machine shows the timezone name as "(UTC-08:00) Pacific Time (US & Canada)" but in application the timezone differs from the client system it shows as "(UTC-08:00) Baja California".
这可能与您在应用程序代码中选择时区的方式有关。在我看来,您正在扫描服务器时区列表并选择第一个符合某些条件的时区。由于这两个时区具有相同的基准偏移量,您可能只是选择了错误的时区,无论如何都不应该这样做。但是因为你没有展示那部分代码,所以我帮不了你太多。
回答您的具体问题:
Whether the TimeZoneInfo class can work automatically work according to the adjusment rule, when we convert from UTC to Local?
是的,可以。
TimeZoneInfo
没有错,关键在于你如何使用它。您可能选择了错误的时区。Do we have to detect the DST for particular datetime using the method
TimeZoneInfoObject.IsDaylightSavingTime(DateTime)
and do conversion?不,您不必为了从 UTC 转换为特定时区而这样做。
ConvertTimeFromUtc
函数将为您处理。Is there any other classes in .Net which can sync with windows timezones?
TimeZoneInfo
是 .NET Framework 中唯一内置的。 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)