想改善这个问题吗?更新问题,使其仅通过editing this post专注于一个问题。
2年前关闭。
我希望将这个问题及其答案作为处理夏时制(尤其是处理实际变更)的权威指南。
如果您要添加任何内容,请执行
许多系统都依赖于保持准确的时间,问题在于夏时制导致的时间变化-向前或向后移动时钟。
例如,一个在接订单系统中有取决于订单时间的业务规则-如果时钟改变,则规则可能不太清楚。订购时间应如何保留?当然,有无数种情况-这只是一种说明。
您如何处理夏令时问题?
解决方案中包含哪些假设? (在此处查找上下文)
同样重要的是,如果不是更重要的话:
您尝试了什么但没有用?
为什么不起作用?
我会对编程,操作系统,数据持久性以及该问题的其他相关方面感兴趣。
一般的答案很好,但是我也想看看细节,特别是如果它们仅在一个平台上可用。
最佳答案
答案和其他数据摘要:(请添加您的答案)
做:
每当您指的是确切的时间时,请按照不受夏令时影响的统一标准坚持时间。 (GMT和UTC在这方面是等效的,但是最好使用术语UTC。请注意,UTC也称为Zulu或Z time。)
如果相反,您选择使用本地时间值来保留时间,则包括该特定时间与UTC的本地时间偏移量(此偏移量可能会在全年中发生变化),以便以后可以明确地解释时间戳。
在某些情况下,您可能需要同时存储UTC时间和等效的本地时间。通常,这是通过两个单独的字段完成的,但是某些平台支持可以将两个字段都存储在单个字段中的datetimeoffset
类型。
将时间戳记存储为数值时,请使用Unix time-这是自1970-01-01T00:00:00Z
以来的秒数(不包括leap秒)。如果需要更高的精度,请改用毫秒。此值应始终基于UTC,而无需进行任何时区调整。
如果以后可能需要修改时间戳,请包括原始时区ID,以便可以确定偏移量是否可能与记录的原始值有所变化。
在安排未来事件时,通常首选本地时间而不是UTC,因为通常会更改偏移量。 See answer和blog post。
当存储整个日期(例如生日和周年纪念日)时,请勿转换为UTC或任何其他时区。
如果可能,以不包括一天中的时间的仅日期数据类型存储。
如果此类类型不可用,请在解释值时始终忽略时间。如果不能保证忽略一天中的时间,请选择中午12:00,而不是午夜00:00,作为该天更安全的代表时间。
请记住,时区偏移量并非总是小时的整数(例如,印度标准时间为UTC + 05:30,而尼泊尔使用UTC + 05:45)。
如果使用Java,则对Java 8和更高版本使用java.time。
大部分java.time功能都被反向移植到ThreeTen-Backport库中的Java 6和7。
ThreeTenABP库中进一步适用于早期的Android(这些项目正式取代了现在位于Joda-Time中的古老的maintenance-mode。 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.js和moment-timezone扩展名一起使用。
如果使用PHP> 5.2,请使用DateTime
和DateTimeZone
类提供的本地时区转换。使用DateTimeZone::listAbbreviations()
-see answer时要小心。为了使PHP具有最新的Olson数据,请定期安装the timezonedb PECL软件包; see answer。
如果使用C ++,请确保使用使用正确实现IANA timezone database的库。这些包括cctz,ICU和Howard Hinnant's "tz" library。
请勿将Boost用于时区转换。虽然its API声称支持标准IANA(又名“ zoneinfo”)标识符,但它属于POSIX样式的数据,而没有考虑每个区域可能具有的丰富变更历史。 (此外,该文件已退出维护。)
如果使用Rust,请使用crudely maps them。
大多数业务规则使用民事时间,而不是UTC或GMT。因此,在应用逻辑之前,计划将UTC时间戳转换为本地时区。
请记住,时区和偏移量不是固定的,可能会发生变化。例如,从历史上看,美国和英国使用相同的日期来“向前跳跃”和“向后倾斜”。但是,在2007年,美国更改了更改时钟的日期。现在,这意味着一年中的48周,伦敦时间和纽约时间之间的时差为5小时,而4周(春季为3个,秋季为1个)为4小时。在涉及多个区域的任何计算中,请注意此类项目。
考虑时间类型(实际事件时间,广播时间,相对时间,历史时间,重复发生的时间),您需要存储哪些元素(时间戳,时区偏移量和时区名称)以进行正确检索-请参见“时间类型” chrono。
在您自己的OS,数据库和应用程序tzdata文件之间以及与世界其他地方之间保持同步。
在服务器上,将硬件时钟和操作系统时钟设置为UTC而不是本地时区。
不管先前的要点如何,服务器端代码(包括网站)都永远不要指望服务器的本地时区特别重要。 this answer。
最好在您的应用程序代码中视情况使用时区,而不是通过配置文件设置或默认值进行全局时区处理。
在所有服务器上使用see answer服务。
如果使用NTP,请记住时间戳记存储在本地时间,而不是UTC。
在处理周期性事件(例如每周电视节目)时,请记住,时间随着DST而变化,并且在各个时区中会有所不同。
始终将日期时间值查询为FAT32(>=
,<
)。
别:
不要混淆“时区”(例如America/New_York
)和“时区偏移”(例如-05:00
)。他们是两个不同的东西。请参见lower-bound inclusive, upper-bound exclusive。
不要使用JavaScript的Date
对象在较早的Web浏览器中执行日期和时间计算,因为ECMAScript 5.1和更低版本的the timezone tag wiki可能会错误地使用夏时制。 (这已在ECMAScript 6/2015中修复)。
永远不要相信客户的时钟。这很可能是不正确的。
不要告诉人们“总是在任何地方使用UTC”。这种广泛的建议是本文档前面介绍的几种有效方案的短视。而是对要使用的数据使用适当的时间参考。 (时间戳记可以使用UTC,但将来的时间安排和仅日期值不应使用。)
测试:
在测试时,请确保您测试的是西半球,东半球,北半球和a design flaw半球中的国家(实际上是在全球的每个季度,所以是4个地区),并且正在进行DST(未进行DST)(给出8个),以及一个国家/地区不使用DST(另外4个覆盖所有区域,总共12个)。
测试DST的转换,即当您当前处于夏季时间时,请从冬季中选择一个时间值。
使用DST测试边界情况,例如UTC + 12时区,使本地时间Southern
测试所有第三方库和应用程序,并确保它们正确处理时区数据。
至少测试半小时时区。
参考:
UTC+13 in summer and even places that are UTC+13 in winter
The detailed timezone
tag wiki page on Stack Overflow
Olson database, aka Tz_database
IETF draft procedures for maintaining the Olson database
Sources for Time Zone and DST
ISO format (ISO 8601)
Mapping between Olson database and Windows Time Zone Ids, from the Unicode Consortium
Time Zone page on Wikipedia
StackOverflow questions tagged dst
StackOverflow questions tagged timezone
Dealing with DST - Microsoft DateTime best practices
其他:
游说您的代表以终止DST的可憎性。我们总是可以希望...
Network Time Protocol on Wikipedia的大厅
关于datetime - 夏令时和时区最佳实践,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46844062/