How does DateTimeOffset deal with daylight saving time?
我知道DateTimeOffset存储UTC日期/时间和偏移量。我也从MSDN博客文章中了解到DateTimeOffset应该用于"使用夏令时"。
我正在努力理解的是DateTimeOffset"夏令时"的工作原理。我的理解,很少有,是夏令时是一个政治决定,不能从纯粹的抵消推断。如果它只存储一个偏移,那么这个结构对DST是否友好呢?
我认为可能有一种方法可以将TimeZoneInfo类与DateTimeOffset结合使用。我该怎么办?
最后,有什么更好的方法可以实现以下目标吗?
(我看过Jon Skeet关于Noda-Time的一些帖子,但我认为它还没有准备好生产,我不知道它是否能很好地融入我们现有的解决方案)。
这是我们的场景。该服务器是出于在英国时间运行的不幸遗留原因。我们的客户开始从澳大利亚投入运营,其中有多个时区。其他国家可以随时投入使用。
我们有一个基于Hardcodet调度程序的调度程序(使用DateTimeOffset)。它工作得很好。但是,在我们的数据库中,我们只存储足够的数据来构造DateTime对象(见下文),在我们的子类和管道代码中我们只使用DateTime,因为最初我们只支持英国用户。
该调度程序负责固定和动员工厂设备。因此,预定事件在用户的DST调整后的当地时间运行至关重要。
用户在我们的网站上输入时间表;目前,它作为星期几,小时和分钟存储在数据库中。当读取数据时,我们为该日,小时和分钟的下一次出现创建一个DateTime对象。我可以自由地改变db结构以另外存储偏移量或时区。
当该日期和时间到达时,调度程序发送命令(并重试一段时间)。它然后在下周的同一天和时间再次运行(虽然该服务实际上已经被回收,然后代码将再次运行)。
我需要实现的是使用从Hardcodet子类调度的调度程序在该时区调整的本地日期和时间触发调度事件。如果DateTimeOffset确实是DST感知的,那么我需要做的就是存储一个偏移并改变我们的管道代码以使用这个结构,但我得到的印象并不是那么简单。 (我们或许可以从工厂的GPS位置获取当前时区,但这是另一天的讨论:))。
-
如果在DST过渡期间"下一个"日期和时间落入差距怎么办?即 那个时间永远不会发生在那一天,因为时间会提前一个小时。 我认为没有一个可以插入的神奇解决方案。
-
@Damien_The_Unbeliever提出了一个很好的观点,反之也应该考虑 - 当地时间可以在同一天发生两次。 当您从LocalDateTime转换为ZonedDateTime时,Noda Time强制您考虑这些选项; .NET没有:(
-
工作大部分都已完成,我现在正在测试 - Noda-Time是神奇的解决方案,因为它告诉我所有关于跳过的时间,映射中的含糊不清等:)
-
在数据库中,我存储星期,小时,分钟和时区。 调度程序使用此数据和Noda-Time计算下次触发事件时的本地时间。 如果有未解决的歧义,它会通过电子邮件发送给我。
DateTimeOffset本身并不真正支持DST,但TimeZoneInfo是。 DateTimeOffset表示固定的时刻 - 因此您可以通过时区感知到达DateTimeOffset。 换句话说,如果我现在在英国要求DateTimeOffset,我最终会得到与UTC相差+1小时的东西。 如果我在12月份在英国要求DateTimeOffset一段时间,我最终会得到一些与UTC相差0小时的东西。
如果您更改数据库以包含偏移量,并且您从用户选择的DateTime(应该是"未指定的")及其时区创建DateTimeOffset,那么这应该为您提供正确的偏移量,并将DST考虑在内。
但要注意的一件事是:如果我现在安排"2年时间"并确定现在的偏差,那么这种抵消在将来可能不正确 - 例如,政府可能会在DST适用时改变,显然这是 不会改变数据库中存储的内容。
-
@ Jon Is Noda时间准备好在这样的场景中使用?
-
@StephenKennedy:我不知道时区计算等方面的任何问题 - 剩下的1.0之前的工作大部分是围绕文本格式化/解析。鉴于我们没有达到1.0,我会谨慎地采用它 - 如果我在你的鞋子里我想要你的特定用例进行大量的测试 - 但是如果你想要使用Noda Time的任何支持,我我很乐意提供帮助,我相信邮件列表中的其他成员也是如此。
-
谢谢乔恩。这里99%的战斗是存储适合db的东西,并根据Job < T >对象的开始时间从该数据构造DateTimeOffset实例。具有有效负载的Job < T >对象可以正常工作,而基础调度程序已经可以正常工作。我将下载Noda Time和RTFM以尝试确定这是否合适。那就是如果我在我的演讲中不成功,我们应该在UTC中做所有事情并让最终用户担心DST,尤其是因为Damien提出的问题:)
-
@StephenKennedy:在UTC中做任何事都应该没问题 - 基本上你应该存储一个对应于单个UTC时间的东西,无论是DateTimeOffset还是其他什么。我真的很想听听你对Noda Time的看法 - 请给我发邮件。
-
@Damien_The_Unbeliever Jon的回答很明显,但我们从那里开始了很多。我使用Noda-Time实现计算,以及模糊处理以解决Damien引发的问题,然后将结果映射到DateTimeOffset并将其输入调度程序。对这一过程的轻松性和对初步结果的满意度给我留下了非常深刻的印象。
-
我根据频率类型建立了一个具有不同频率(每周,每月,每年)和规律性(每X周/月/年)的重复事件的调度系统,并且每周频率还允许指定一周中的特定日期(例如,每周周二和周四,每两周一次)。它直接计算"now"之前的最近到期日期,但这不能在UTC中完成,因为小时的变化可能会改变当天。如果要在当地时间每周二晚上11点运行,我必须使用当地日期。 DST导致小时在一年中的整个时间段内发生变化。
-
令人困惑的部分是,如果我构造一个DateTimeOffset,其时间为凌晨3点(2016年3月13日恰好是DST的开始),并且我指定了-5小时的偏移量,那么TimeOfDay属性在凌晨3点保持正确;但是,LocalDateTime.TimeOfDay属性表示它是凌晨4点。 DateTimeOffset的时间似乎来自一个名为ClockDateTime的私有变量,我可以在调试器中看到它。本地日期时间和时钟日期时间具有不同的刻度值。所有这些之间的关系并不明显。
-
@Triynko:说实话,听起来这应该都是一个新问题。