在 C# 中使用夏令时处理时区

Tho*_*mas 2 .net c# timezone

我们有一个与航空相关的应用程序,特别是航班。

时间必须存储在本地,所以我选择使用 UTC 时间 + 一个偏移量,但现在我意识到这是一个糟糕的选择:

通过将时区存储为偏移量,我无法跟踪原始时区,这在处理夏令时会产生影响。

例如,我可以将 Alpine、UT 中的时间存储为 UTC 时间和 -6 偏移量,还可以将 Phoenix、AZ 中的时间存储为 UTC 时间和 -6 偏移量。

但是当夏令时来临时,Alpine 的时间会改变,而 Phoenix 不会。

所以,我需要存储正确的时区,并且我已经看到还有不同的列表具有不同的语法,所以我假设有不同的标准。

在 C# 中,使用本地时区存储本地时间以使其适用于夏令时更改的最佳选择是什么?

Mat*_*int 5

从问题评论中的讨论中,我了解到您正在处理航班时间表 - 即未来航班打算起飞的时间。这确实是本地时间比 UTC 时间更重要的情况。

由于您有当地时间和出发地点(例如:盐湖城下午 5:00),那么您应该在计划出发时间的数据库中存储两个值:

  • 17:00 - 出发的相关当地时间
  • SLC - 时间相关的位置

如果这是此航班的特定事件,那么您还应该存储日期:

  • 2018-06-01T17:00-出发的具体相关当地时间
  • SLC - 当地时间相关的位置

这些是与您的业务用例上下文相关的详细信息。不要通过将它们转换为 UTC 来忽略它们

也就是说,您可能会考虑将它们存储为DateTimeOffset( 2018-06-01T17:00-06:00),这使得对于给定实例转换为 UTC 变得微不足道。但是这种方法有两个问题:

  • 它不能与重复一起工作,因为偏移量可能会改变。
  • 即使对于单个实例,偏移量也可能会发生变化 - 如果控制时区的政府决定在该事件生效之前更改其标准偏移量或夏令时规则。如果您确实采取了某种DateTimeOffset方法或基于 UTC 的方法,您必须准备好在面对此类变化时重新计算未来的事件。(有关这方面的更多信息,请参阅我的博客文章:关于埃及时区变化的时机时区混乱不可避免。还有无数其他例子。)

关于位置 - 因为您正在处理上下文适用于航空业的数据,我建议使用SLC我上面显示的IATA 机场代码。在其他上下文中,可能会存储 IANA 时区标识符,如America/Denver,或 Windows 时区标识符,如Mountain Standard Time

您可能会发现我的“机场时区”要点(代码和输出表)对处理 IATA 机场代码很有用。您必须决定这些数据将如何流经您的系统。如果您在 Windows 上运行并希望使用TimeZoneInfo该类将时间转换为不同的时区,请使用此处显示的 Windows 时区 ID。如果您想改用 IANA 时区 ID,请考虑使用Noda Time,或者您可以使用我的TimeZoneConverter库。这里有几个不同的选项,所以仔细探索它们并选择对你有意义的选项。

恕我直言,野田时间将是一个不错的选择。您不仅会获得出色的时区支持,而且您还可以使用与所描述的场景非常吻合的类型LocalTime或类型LocalDateTime