TimeZoneInfo.GetUtcoffset有多可靠?

我在GetUtcoffset()对象中使用函数TimeZoneInfo来获取特定日期时间的Utc偏移值。通常,夏令时会遵循特定的规则,例如“ 从10月的第一个星期日开始,到4月的第一个星期日结束”(美国东部标准时间),因此我相信这样的结果函数产生。

但我确实想知道,如果夏令时由于政府的决定而延迟或改变,结果将会怎样?过去,有几次澳大利亚政府违反了某些事件的夏令时规则。在这种情况下,调用GetUtcoffset()会产生不正确的结果,还是库足够聪明以至于“偶尔”从Internet上的某些来源获取夏令时更新?

用法: 我正在设计一个停车管理系统。一个数据库在时区不同的多个客户端之间共享。停车事件的时间可以作为法庭上的证据,因此,正确安排停车时间非常重要。当系统收到车辆停放的通知时,系统将生成到达时间。鉴于通知可能来自不同时区的远程站点,我想知道我是否可以可靠地使用时区在客户端站点上锻炼当前日期时间。

示例:

string clientTimeZoneId = "AUS Eastern Standard Time";
var utcTime = DateTime.UtcNow;
var clientTimeZone = TimeZoneInfo.FindSystemTimeZoneById(clientTimeZoneId);
var arrivalTime = utcTime.Add(clientTimeZone.GetUtcOffset(utcTime));

这是GetUtcOffset函数变得重要的地方。鉴于在2019-2020年“ AUS东部标准时间”的夏令时于2020年4月5日结束,因此在6日调用GetUtcOffset将提供+10:00:00。但是,如果出于任何原因(例如奥运会的事件),DST扩展到了10,则arrivalTime可能会错误地表示一个小时,具体取决于GetUtcOffset的值。

目前,我们的系统管理员必须每年手动更新数据库中的夏时制日期,但是不必这样做会很高兴。我不确切知道政府在这些事件中做了什么,但是他们必须将更新发送到某个地方,否则受影响时区中的所有计算机的时间都不正确。因此,回到我最初的问题,TimeZoneInfo将从任何“ DST源”中获取数据吗?

shen453927 回答:TimeZoneInfo.GetUtcoffset有多可靠?

您的问题分为两个部分。我将从您首先给出的代码示例开始:

var arrivalTime = utcTime.Add(clientTimeZone.GetUtcOffset(utcTime));

这是错误地应用了偏移量。由于utcTime的{​​{1}}属性设置为Kind,因此在调用DateTimeKind.Utc之后的结果值也是如此。因此,您无需调整偏移量,而是实际上选择了其他时间点(未来10或11个小时)。 (有关此示例的幽默示例,请参见this Dilbert comic。)

您可以通过几种不同的方式来做到这一点:

  • 您可以在Add上使用ConvertTimeConvertTimeFromUtc方法。结果日期和时间将与以前相同,但是TimeZoneInfo将正确设置为Kind

    DateTimeKind.Unspecified
  • 您可以使用获取的偏移量来构建DateTime utcNow = DateTime.UtcNow; DateTime arrivalTime = TimeZoneInfo.ConvertTime(utcNow,clientTimeZone);

    DateTimeOffset
  • 您可以使用DateTimeOffset utcTime = DateTimeOffset.UtcNow; DateTimeOffset arrivalTime = utcTime.ToOffset(clientTimeZone.GetUtcOffset(utcTime)); 更轻松地创建DateTimeOffset。这样做与以前的代码相同,但是更干净。

    TimeZoneInfo.ConvertTime

对于您所描述的情况,我建议使用DateTimeOffset utcTime = DateTimeOffset.UtcNow; DateTimeOffset arrivalTime = TimeZoneInfo.ConvertTime(utcTime,clientTimeZone); 。您将拥有本地时间和与UTC的时差。存储整个东西。 (如果您对数据库使用Microsoft SQL Server之类的东西,则只需使用单个DateTimeOffset字段。)

同时具有本地时间和偏移量的好处是,即使发生了某些变化,您也将有足够的数据来恢复通用时间中的实际点,并且您仍然可以使用以下格式的数据:由当地时间合理化。 (或者,您可以将UTC时间和本地时间都存储在两个单独的字段中。有时这还是有助于建立索引的目的。)

关于您关于数据可靠性的第二个问题,我建议您阅读this question及其答案。一般而言-是的。数据可靠。但是,让我们解开您描述的有关政府偏差的情况。

  • 首先,您是否知道时区数据中未记录的任何此类已经发生的偏差?看一下the history on timeanddate.comin the sources of the IANA time zone database。如果存在未记录的偏差,则可能应该记录。请将此类信息发送到the tz discussion list。其他所有人都可以从那里获取更改。

  • 对于Windows,您可以在datetimeoffset上检查注册表数据。请参阅Josh Free撰写的Exploring Windows Time Zones... Microsoft博客文章,以了解它们的工作原理。对于悉尼来说,记录的规则最后一次更改是在2008年,与IANA以及时间和日期信息保持一致。

  • 请记住,Windows假定2007年悉尼规则在之前的所有时间点都是相同的。它没有IANA数据库具有的历史深度。例如,Windows不知道IANA数据库的注释中指出的2000年奥运会的偏差。如果此类历史更改对您的应用程序很重要,那么您将需要使用NodaTime中的TZDB提供程序。 (尽管我无法想象为什么您今天的停车申请需要那个历史记录。)

那么,如果澳大利亚政府决定在将来做出偏离,那会发生什么呢?

  • 如果他们给出了足够的通知,那么IANA和Windows都会选择并通过Windows Update分发更改。您的Windows计算机将自动收到更改,并且您的应用程序将正确兑现偏差。

  • 如果他们没有提供足够的通知,则Microsoft将遵循aka.ms/time中描述的策略,为变通办法提供指导,并努力尽快做出更改。实际的。 IANA也可能会急于做出更改,但是分发时间会根据实现方式而有所不同(Linux,Java,Python,Android,Noda Time等。每种都以自己的方式分发时区数据。)

短通知时区确实在过去发生过变化,并且存在问题。幸运的是,近年来它们的数量有所减少。我在2016年就在此发布了博客。请参阅:On the Timing of Time Zone Changes

TL; DR:

  

因此,回到我最初的问题,TimeZoneInfo将从任何“ DST源”中获取数据吗?

  • 对于Windows,来源是Microsoft通过Windows Updates。如果您使系统保持最新,则您的应用程序将具有正确的时区数据。这些更新将在this blog上宣布。

  • 对于在其他平台(Linux,OSX)上运行的.NET,最终来源是IANA time zone database,其数据由您正在运行的平台分发。例如,Ubuntu Linux ships a tzdata package具有这些更新。

本文链接:https://www.f2er.com/3155316.html

大家都在问