当前位置: 首页 > 知识库问答 >
问题:

TimeZoneInfo. GetUtcoffset的可靠性如何?

方砚
2023-03-14

我正在使用TimeZoneInfo对象中的函数GetUtcoffset()来获取特定日期时间的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源”获取数据吗?

共有1个答案

金令
2023-03-14

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

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

这是错误地应用偏移量。因为utcTime将其Kind属性设置为DateTimeKind。Utc,调用Add后的结果值也是如此。因此,你不是在调整偏移量,而是在选择一个不同的时间点(未来10或11个小时)。

有几种不同的方法可以代替:

>

  • 您可以在TimeZoneInfo上使用ConvertTimeConvertTimeFromUtc方法。生成的日期和时间将与之前相同,但Kind将正确设置为DateTimeKind。未指定的

      DateTime utcNow = DateTime.UtcNow;
      DateTime arrivalTime = TimeZoneInfo.ConvertTime(utcNow, clientTimeZone);
    

    您可以使用检索到的偏移量构建一个DateTimeOffset

      DateTimeOffset utcTime = DateTimeOffset.UtcNow;
      DateTimeOffset arrivalTime = utcTime.ToOffset(clientTimeZone.GetUtcOffset(utcTime));
    

    您可以使用TimeZoneInfo更轻松地创建DateTimeOffset。ConvertTime。这与之前的代码相同,但更干净。

      DateTimeOffset utcTime = DateTimeOffset.UtcNow;
      DateTimeOffset arrivalTime = TimeZoneInfo.ConvertTime(utcTime, clientTimeZone);
    

    对于您描述的场景,我建议使用DateTimeOffset。您将获得当地时间和UTC的偏移量。把所有的东西都存起来。(如果您的数据库使用的是Microsoft SQL Server之类的工具,只需使用一个datetimeoffset字段即可。)

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

    至于你关于数据可靠性的第二个问题,我建议阅读这个问题,以及我对它的回答。但总的来说——是的。数据是可靠的。但是,让我们把你描述的关于政府偏差的场景拆开。

    >

  • 首先,您是否知道已经发生的任何未记录在时区数据中的偏差?查看一下时间和日期的历史记录。com,或在IANA时区数据库的源代码中。如果存在未记录的偏差,则可能应该记录。请将这些信息发送到tz讨论列表。其他人都从那里得到了变化。

    对于Windows,您可以在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\MONtVersion\Time Zones\AUS East Standard Time\DynamicDST处检查注册表数据。请参阅探索Windows时区... Josh Free的Microsoft博客文章以了解它们是如何工作的。对于悉尼,记录的最后一次规则更改是在2008年,这与IANA和时间日期信息保持一致。

    请记住,Windows假定2007年悉尼奥运会的规则在那之前的所有时间点都是相同的。它没有IANA数据库的历史深度。例如,Windows不知道IANA数据库评论中提到的2000年奥运会的偏差。如果这样的历史更改对应用程序很重要,那么您需要在NodeTime中使用TZDB提供程序。(尽管我无法想象,为什么你会需要这种历史记录来制作今天的停车场应用程序。)

    那么,如果澳大利亚政府决定在未来做出改变,会发生什么呢?

    >

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

    如果他们没有提供足够的通知,那么微软将遵循aka.ms/time中描述的策略,为解决方法提供指导,并努力尽快完成更改。IANA也可能会匆忙进行更改,但分发时间因实施而异(Linux、Java、Python、Android、Noda Time等)。每个人都以自己的方式分发时区数据。)

    短时间通知的时区变化在过去确实发生过,而且是有问题的。幸运的是,近年来它们变少了。我在2016年写了一篇博客。请参阅:关于时区变化的时机。

    TL;博士:

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

    >

  • 对于Windows,源代码是Microsoft via Windows Update。如果您的系统保持最新,那么您的应用程序将具有正确的时区数据。此类更新将在本博客上公布。

    对于NET在其他平台(Linux、OSX)上运行时,最终的源代码是IANA时区数据库,其数据由您正在运行的平台分发。例如,Ubuntu Linux附带了一个带有这些更新的tzdata包。

  •  类似资料:
    • 密码 考虑以下情况... 事务已启动(使用Spring@Transactional annotation) 消息丢失了吗? 如果不是,那么如何在事务下从队列中读取消息(步骤2)? 是否使用了某种队列浏览器,以便从队列中读取消息但不消费?

    • 可靠性指标 很多领域一般都喜欢谈服务可靠性,用几个 9 来说事。这几个 9 其实是粗略代表了概率意义上系统能提供服务的可靠性指标,最初是电信领域提出的概念。 下表给出不同指标下,每年允许服务出现不可用时间的参考值。 指标 概率可靠性 每年允许不可用时间 典型场景 一个九 90% 1.2 个月 不可用 二个九 99% 3.6 天 普通单点 三个九 99.9% 8.6 小时 普通企业 四个九 99.9

    • 互联网做得太棒了,以至于大多数人将它看作像太平洋这样的自然资源,而不是什么人工产物。上一次出现这种大规模且无差错的技术, 你还记得是什么时候吗? ——阿兰·凯在接受Dobb博士杂志采访时说(2012年) [TOC] 现今很多应用程序都是 数据密集型(data-intensive) 的,而非 计算密集型(compute-intensive) 的。因此CPU很少成为这类应用的瓶颈,更大的问题通常来自数

    • 通过主动构建过程掌控架构 您的软件架构和您所期望的一样吗?当架构落实到代码时,它并不总是 我们曾经互相讨论并预想的那个。在本期的 让开发自动化中,Paul Duvall 将演示如何通过使用 JUnit、JDepend 和 Ant 编写 有关测试来发现架构偏差,从而做到在发生问题之前主动发现问题。 我在曾经从事的很多软件开发项目中观察到,软件开发中一直存在这样一种现象:您实际拥有的架构往往与想象中的

    • 海蓝(navy blue)是最为大众所接受的颜色之一。采用这种颜色的色彩组合可解释成可靠、值得信赖的色彩。这类组合也带有不可置疑的权威感。警官、海军军官或法官都穿着深色、稳定的海军蓝,以便在值勤时表现出统率、支配的权威感。 当海军蓝用红和金色来强调时,会变得较不严肃,但仍表达出坚定、有力量的感觉。 补色色彩组合 原色色彩组合 单色色彩组合 21 65 17 65 33 1 65 67 70 65

    • 我使用Vaadin14,为了避免在用户双击按钮而不是只单击一次时多次发送请求,我在实例上调用。 对于某些按钮,这是不够的:按钮仍然可以被多次单击。在检查Chrome devtools中的dom时,我可以看到为这些按钮设置了属性: 我怀疑这是事件处理程序调用顺序的问题(要禁用的处理程序应该在发送请求的处理程序之前调用)。