我们有一个与航空相关的应用程序,特别是航类。
时间必须存储在本地,所以我选择使用 UTC 时间 + 偏移量,但现在我意识到这是一个糟糕的选择:
通过将时区存储为偏移量,我忘记了原始时区,这在处理夏令时时会产生影响。
例如,我可以将犹他州阿尔卑斯山的时间存储为 UTC 时间和 -6 偏移量,也可以将亚利桑那州凤凰城的时间存储为 UTC 时间和 -6 偏移量。
但是当夏令时到来时,Alpine 的时间会发生变化,而 Phoenix 则不会。
因此,我需要存储正确的时区,并且我看到也有不同的列表具有不同的语法,所以我假设有不同的标准。
在 C# 中,将本地时间与本地时区一起存储以使其适用于夏令时更改的最佳选择是什么?
最佳答案
根据问题评论中的讨论,我了解到您正在处理航类时刻表 - 即 future 航类计划起飞的时间。这确实是本地时间比 UTC 时间更重要的情况。
既然您有本地时间和出发地点(例如:盐湖城下午 5:00),那么您应该在计划出发时间的数据库中存储两个值:
17:00
- 出发的相关本地时间SLC
- 时间相关的位置
如果这是此航类的特定事件,那么您还应该存储日期:
2018-06-01T17:00
- 具体出发的相关本地时间SLC
- 本地时间相关的位置
这些是与您的业务用例上下文相关的详细信息。不要通过将它们转换为 UTC 而忽略它们。。
也就是说,您可以考虑将它们存储为 DateTimeOffset
(2018-06-01T17:00-06:00
),这使得转换为 UTC 变得微不足道给定实例。但是这种方法有两个问题:
- 它不能用于重复,因为偏移量可能会改变。
- 即使是单个实例,偏移量也可能发生变化 - 如果控制时区的政府决定在该事件生效之前更改其标准偏移量或夏令时规则。如果您确实采用了
DateTimeOffset
方法或基于 UTC 的方法,则必须准备好在面对此类更改时重新计算 future 事件。 (有关这方面的更多信息,请参阅我的博客文章: On the Timing of Time Zone Changes 和 Time Zone Chaos Inevitable in Egypt 。还有无数其他示例。)
关于位置 - 因为您正在处理在上下文中适用于航空业的数据,所以我建议使用 IATA 机场代码,例如我上面显示的 SLC
。在其他情况下,可能会存储一个 IANA 时区标识符,如 America/Denver
,或一个 Windows 时区标识符,如 Mountain Standard Time
。
您可能会发现 my "Airport Time Zones" gist (code and output table)对于处理 IATA 机场代码非常有用。您必须决定数据将如何流经您的系统。如果您在 Windows 上运行并且想要使用 TimeZoneInfo
类将时间转换为不同的时区,请使用此处显示的 Windows 时区 ID。如果您想改用 IANA 时区 ID,请考虑使用 Noda Time ,或者你可以使用我的 TimeZoneConverter图书馆。这里有几个不同的选项,因此请仔细探索它们并选择对您有意义的选项。
Noda Time 将是一个不错的选择,恕我直言。您不仅会获得出色的时区支持,而且还能够使用 LocalTime
或 LocalDateTime
等类型,它们与所描述的场景非常吻合。
关于c# - 在 C# 中使用夏令时处理时区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49965128/