Closed 。这个问题需要多问focused 。目前不接受答案。
我希望使这个问题及其答案成为处理夏令时的权威指南,特别是处理实际的转换。
如果您有什么要补充的,请做
许多系统都依赖于保持准确的时间,问题在于夏令时导致的时间变化 - 将时钟向前或向后移动。
例如,订单接收系统中的业务规则取决于订单时间 - 如果时钟发生变化,规则可能不会那么清晰。订单的时间应该如何持久化?当然,场景有无数种——这只是一个说明性的场景。
您是如何处理夏令时问题的?
您的解决方案包含哪些假设? (在这里寻找上下文)
同样重要的是:
我对编程、操作系统、数据持久性和问题的其他相关方面感兴趣。
一般答案很好,但我还想查看详细信息,特别是如果它们仅在一个平台上可用。
答案和其他数据摘要:(请添加您的)
Do:
每当您提到确切的时间时刻时,请根据不受夏令时影响的统一标准来保留时间。 (GMT 和 UTC 在这方面是等效的,但最好使用术语 UTC。请注意,UTC 也称为Zulu or Z time.)
相反,如果您选择使用本地时间值保留(过去的)时间,请包括该特定时间相对于 UTC 的本地时间偏移量(该偏移量可能会在一年中发生变化),以便稍后可以明确地解释时间戳。
在某些情况下,您可能需要存储both UTC 时间和等效的本地时间。通常这是通过两个单独的字段完成的,但某些平台支持datetimeoffset
可以将两者存储在单个字段中的类型。
将时间戳存储为数值时,请使用Unix时间 - 这是自那时以来的整秒数1970-01-01T00:00:00Z
(不包括闰秒)。如果您需要更高的精度,请改用毫秒。该值应始终基于 UTC,而不进行任何时区调整。
如果您稍后可能需要修改时间戳,请包含原始时区 ID,以便您可以确定偏移量是否相对于记录的原始值已发生更改。
在安排未来的事件时,通常首选当地时间而不是 UTC,因为偏移量发生变化是很常见的。查看答案 , and 博客文章 .
When storing whole dates, such as birthdays and anniversaries, do not convert to UTC or any other time zone.
如果可能,请存储在不包含一天中的时间的仅日期数据类型中。
如果此类类型不可用,请确保在解释该值时始终忽略当天的时间。如果您不能确保当天的时间会被忽略,请选择中午 12:00 而不是午夜 00:00 作为当天更安全的代表时间。
请记住,时区偏移并不总是整数小时(例如,印度标准时间为 UTC+05:30,尼泊尔使用 UTC+05:45)。
如果使用 Java,请使用java.time 适用于 Java 8 及更高版本。
其中大部分java.time 功能向后移植到 Java 6 和 7三十后端口 图书馆。
进一步适配了早期的Android(三十ABP 图书馆。
这些项目正式取代了令人尊敬的乔达时间 ,现在在维护模式 。 Joda-Time、ThreeTen-Backport、三十额外 , java.time 课程,以及JSR 310 由同一个人领导,史蒂芬·科尔伯恩 .
如果使用.NET ,考虑使用野田时间 .
如果在没有 Noda Time 的情况下使用 .NET,请考虑DateTimeOffset
通常是比DateTime
.
如果使用 Perl,请使用DateTime .
如果使用 Python 3.9 或更高版本,请使用内置zoneinfo 用于处理时区。否则,使用dateutil or arrow 。年龄较大的pytz 一般情况下可以避免图书馆。
如果使用 JavaScript,请避免使用旧版本moment.js or 时刻时区 库,因为它们不再被积极维护。请参阅Moment.js 项目状态 更多细节。相反,请考虑Luxon , date-fns , day.js , or js-joda .
如果使用 PHP > 5.2,请使用由DateTime
, and DateTimeZone
类。使用时要小心DateTimeZone::listAbbreviations()
- 查看答案 。要使 PHP 保持最新的 Olson 数据,请定期安装时区数据库 PECL封装;查看答案 .
If using C++, be sure to use a library that uses the properly implements the IANA timezone database . These include cctz , ICU , and Howard Hinnant's "tz" library . In C++20 the latter is adopted into the standard <chrono>
library.
不使用Boost 用于时区转换。尽管its API 声称支持标准 IANA(又名“zoneinfo”)标识符,它粗略地映射它们 POSIX 风格的数据,而不考虑每个区域可能有的丰富的变化历史。 (此外,该文件已不再维护。)
如果使用 Rust,请使用chrono .
大多数业务规则使用民用时间,而不是 UTC 或 GMT。因此,在应用应用程序逻辑之前,计划将 UTC 时间戳转换为本地时区。
请记住,时区和偏移量不是固定的,可能会发生变化。例如,历史上美国和英国使用相同的日期来“向前”和“向后”。然而,2007 年,美国更改了时钟更改的日期。这意味着一年中有 48 周伦敦时间与纽约时间相差 5 小时,而 4 周(春季 3 周,秋季 1 周)则相差 4 小时。在涉及多个区域的任何计算中请注意此类事项。
考虑时间类型(实际事件时间、广播时间、相对时间、历史时间、重复时间),您需要存储哪些元素(时间戳、时区偏移量和时区名称)才能正确检索 - 请参阅《时间类型》这个答案 .
让您的操作系统、数据库和应用程序 tzdata 文件在它们之间与世界其他地方保持同步。
在服务器上,将硬件时钟和操作系统时钟设置为 UTC 而不是本地时区。
不管前面的要点如何, 服务器端代码,包括网站,应该never 期望服务器的本地时区是任何特定的时区。查看答案 .
更喜欢在应用程序代码中根据具体情况处理时区,而不是通过配置文件设置或默认值全局处理时区。
Use NTP 所有服务器上的服务。
如果使用FAT32 ,请记住时间戳存储为本地时间,而不是 UTC。
在处理重复发生的事件(例如每周电视节目)时,请记住时间会随着 DST 的变化而变化,并且不同时区的时间也会有所不同。
始终将日期时间值查询为包含下限,排除上限 (>=
, <
).
Don't:
不要混淆“时区”,例如America/New_York
带有“时区偏移”,例如-05:00
。他们是两个不同的东西。看时区标签 wiki .
不要使用 JavaScriptDate
对象在旧版 Web 浏览器中执行日期和时间计算,如 ECMAScript 5.1 及更低版本设计缺陷 这可能会错误地使用夏令时。 (此问题已在 ECMAScript 6 / 2015 中修复)。
永远不要相信客户的时钟。这很可能是不正确的。
不要告诉人们“始终在任何地方使用 UTC”。这种广泛传播的建议是对本文档前面描述的几个有效场景的短视。相反,请为您正在使用的数据使用适当的时间参考。 (时间戳 可以使用 UTC,但未来时间安排和仅日期值不应使用。)
Testing:
测试时,请确保测试西方、东方、北方和Southern 半球(实际上在全球每个季度,因此有 4 个区域),正在进行和未进行 DST(给出 8 个),以及一个不使用 DST 的国家(另外 4 个覆盖所有区域,总共 12 个)。
测试 DST 的转换,即当前处于夏季时间时,选择冬季的时间值。
测试边界情况,例如时区为 UTC+12,采用 DST,使本地时间夏季 UTC+13,甚至冬季 UTC+13 的地方
测试所有第三方库和应用程序,并确保它们正确处理时区数据。
至少测试半小时时区。
参考:
详细的timezoneStack Overflow 上的标签 wiki 页面
Olson 数据库,又名 Tz_database
IETF 起草维护 Olson 数据库的程序
时区和 DST 来源
ISO 格式 (ISO 8601)
Olson 数据库和 Windows 时区 ID 之间的映射(来自 Unicode 联盟)
维基百科上的时区页面
StackOverflow 问题已标记dst
StackOverflow 问题已标记timezone
处理 DST - Microsoft DateTime 最佳实践
维基百科上的网络时间协议
Other:
游说您的代表结束令人憎恶的夏令时。我们总是可以希望...
大堂为地球标准时间
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)