admin

Daylight saving time and time zone实践

sql

我希望使这个问题及其答案成为处理夏时制(尤其是处理实际变更)的权威指南。

如果您要添加任何内容,请执行

许多系统都依赖于保持准确的时间,问题在于夏时制导致的时间变化-向前或向后移动时钟。

例如,一个在接订单系统中有取决于订单时间的业务规则-如果时钟改变,则规则可能不那么清楚。订购时间应如何保留?当然,有无数种情况-这只是一种说明性的情况。

您如何处理夏时制问题?
什么假设是您解决方案的一部分?(在此处查找上下文)
同样重要的是,如果不是更多的话:

您尝试了什么但没有成功?
为什么不起作用?
我将对编程,操作系统,数据持久性以及该问题的其他相关方面感兴趣。

通用答案很好,但是我也想查看详细信息,特别是如果它们仅在一个平台上可用。


阅读 124

收藏
2021-05-10

共1个答案

admin

  • 每当您指的是确切的时间时,请按照不受夏时制影响的统一标准坚持时间。(GMT和UTC在这方面是等效的,但最好使用术语UTC。请注意,UTC也称为Zulu或Z time。)
  • 如果相反,您选择使用本地时间值来保留时间,则包括该特定时间与UTC的本地时间偏移量(此偏移量可能会全年变化),以便以后可以明确地解释时间戳。
  • 在某些情况下,你可能需要存储两个UTC时间和等效本地时间。通常,这是通过两个单独的字段完成的,但是某些平台支持datetimeoffset可以将两个字段都存储在一个字段中的类型。
  • 将时间戳记存储为数值时,请使用Unix时间-这是自此以来的总秒数1970-01-01T00:00:00Z(不包括leap秒)。如果需要更高的精度,请改用毫秒。此值应始终基于UTC,而无需进行任何时区调整。
  • 如果以后可能需要修改时间戳,请包括原始时区ID,以便可以确定偏移量是否可能与记录的原始值有所变化。
  • 在安排未来事件时,通常首选本地时间而不是UTC,因为通常会更改偏移量。 请参阅答案和博客文章。
  • 当存储整个日期(例如生日和周年纪念日)时,请勿转换为UTC或任何其他时区。
  • 如果可能,以不包括一天中的时间的仅日期数据类型存储。
  • 如果没有这种类型,请在解释该值时始终忽略时间。如果您不能保证忽略一天中的时间,请选择中午12:00,而不是午夜00:00,作为该天更安全的代表时间。
  • 请记住,时区偏移量并非总是小时的整数(例如,印度标准时间为UTC + 05:30,而尼泊尔使用UTC + 05:45)。
  • 如果使用Java,则将Java.time用于Java 8及更高版本。
  • 大部分java.time功能都被反向移植到ThreeTen-Backport库中的Java 6和7中。
  • 在ThreeTenABP库中进一步适用于早期的Android(<26)。
  • 这些项目正式取代了古老的Joda-Time,现在它处于维护模式。Joda-Time,ThreeTen-Backport,ThreeTen-Extra,java.time类和JSR 310由同一个人Stephen Colebourne领导。
  • 如果使用.NET,请考虑使用Noda Time。
  • 如果在没有Noda Time的情况下使用.NET,DateTimeOffset则通常认为它是比更好的选择DateTime。
  • 如果使用Perl,请使用DateTime。
  • 如果使用Python,请使用pytz或dateutil。
  • 如果使用JavaScript,请使用带有moment-timezone扩展名的moment.js。
  • 如果使用PHP> 5.2,请使用DateTime和DateTimeZone类提供的本地时区转换。使用时请小心DateTimeZone::listAbbreviations()-请参阅答案。为* 了使PHP具有最新的Olson数据,请定期安装timezonedb PECL软件包;
  • 如果使用C ++,请确保使用使用正确实现IANA时区数据库的库。这些包括cctz,ICU和Howard Hinnant的“ tz”库。
  • 不要将Boost用于时区转换。尽管其API声称支持标准IANA(又名“ zoneinfo”)标识符,但它粗略地将它们映射到POSIX样式的数据,而无需考虑每个区域可能具有的丰富变更历史。(此外,该文件已退出维护。)
    如果使用Rust,请使用chrono。
  • 大多数业务规则使用民事时间,而不是UTC或GMT。因此,在应用逻辑之前,计划将UTC时间戳转换为本地时区。
    请记住,时区和偏移量不是固定的,可能会发生变化。例如,从历史上看,美国和英国使用相同的日期来“向前跳跃”和“向后倾斜”。但是,在2007年,美国更改了更改时钟的日期。现在,这意味着一年中的48周,伦敦时间与纽约时间之间的时差为5小时,而4周(春季为3个,秋季为1个)为4小时。* 在涉及多个区域的任何计算中,请注意此类项目。
  • 考虑时间类型(实际事件时间,广播时间,相对时间,历史时间,重复时间),您需要存储哪些元素(时间戳,时区偏移量和时区名称)以进行正确检索-请参见这个答案。
  • 在您自己的OS,数据库和应用程序tzdata文件之间以及与世界其他地方之间保持同步。
  • 在服务器上,将硬件时钟和操作系统时钟设置为UTC而不是本地时区。
  • 不管前面的项目点,服务器端代码,包括网站,应该从来没有想到的服务器的本地时区是什么特别。 见答案。
  • 最好在您的应用程序代码中视情况使用时区,而不是通过配置文件设置或默认值进行全局时区处理。
  • 在所有服务器上使用NTP服务。
  • 如果使用FAT32,请记住时间戳记存储在本地时间,而不是UTC。
  • 在处理重复事件(例如每周电视节目)时,请记住,时间随着DST而变化,并且在各个时区中会有所不同。
  • 总是查询日期时间值作为下限以下,上界独占(>=,<)。

Don’t::

  • 不要将“时区”America/New_York与“时区偏移”(如)混淆-05:00。他们是两个不同的东西。请参阅时区标签Wiki。
  • 不要使用JavaScript的Date对象在较旧的Web浏览器中执行日期和时间计算,因为ECMAScript * 5.1及更低版本具有设计缺陷,可能会错误地使用夏时制。(这已在ECMAScript 6/2015中修复)。
  • 永远不要相信客户的时钟。这很可能是不正确的。
  • 不要告诉人们“总是在任何地方使用UTC”。这种广泛的建议是本文档前面介绍的几种有效方案的短视。而是对要使用的数据使用适当的时间参考。(时间戳记可以使用UTC,但将来的时间安排和仅日期值不应使用。)

测试:

  • 测试时,请确保您测试在西部,东部,北部和国家南方(在地球的每个季度其实,这样4个区域)半球,而期间双方DST和不(给8),并且做了国家* 不要使用DST(另外4个覆盖所有区域,总共12个)。
  • 测试DST的转换,即当您当前处于夏季时间时,请从冬季中选择一个时间值。
  • 使用DST测试边界情况,例如时区为UTC + 12,将夏令时设为本地时间UTC + 13,冬季将夏令时设为UTC + 13
  • 测试所有第三方库和应用程序,并确保它们正确处理时区数据。
    至少测试半小时时区。
2021-05-10