当您指的是一个确切的时间点时,请根据不受夏令时影响的统一标准来坚持时间。 (GMT 和 UTC 在这方面是等价的,但最好使用 UTC 一词。请注意,UTC 也称为 Zulu 或 Z 时间。)
如果您选择使用本地时间值保留时间,请包含与 UTC 的本地时间偏移量,以便稍后可以明确地解释时间戳。
在某些情况下,您可能需要同时存储 UTC 时间和等效的本地时间。这通常使用两个单独的字段来完成,但有些平台支持可以将两者都存储在单个字段中的 datetimeoffset 类型。
将时间戳存储为数值时,请使用 Unix 时间 - 这是自 1970-01-01T00:00:00Z 以来的整秒数(不包括闰秒)。如果您需要更高的精度,请改用毫秒。此值应始终基于 UTC,无需任何时区调整。
如果您以后可能需要修改时间戳,请包含原始时区 ID,以便确定偏移量是否可能与记录的原始值有所不同。
在安排未来事件时,通常首选当地时间而不是 UTC,因为偏移量经常发生变化。请参阅答案和博文。
请记住,时区偏移并不总是整数小时(例如,印度标准时间是 UTC+05:30,尼泊尔使用 UTC+05:45)。
如果使用 Java,对 Java 8 使用 java.time,或者对 Java 7 或更低版本使用 Joda Time。
如果使用 .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”)标识符,但它粗略地将它们映射到固定偏移量,而不考虑每个区域可能发生的丰富更改历史。
(另外,该文件已停止维护。)
大多数业务规则使用民用时间,而不是 UTC 或 GMT。因此,在应用应用程序逻辑之前,请计划将 UTC 时间戳转换为本地时区。
请记住,时区和偏移量不是固定的,可能会发生变化。例如,历史上美国和英国使用相同的日期来“前进”和“后退”。
但是,美国在 2007 年更改了时钟更改的日期。现在这意味着一年中的 48 周伦敦时间和纽约时间之间的差异是 5 小时,而 4 周(春季 3 周,秋季 1 周)是 4 小时。在涉及多个区域的任何计算中,请注意此类项目。
考虑时间类型(实际事件时间、广播时间、相对时间、历史时间、重复时间)需要存储哪些元素(时间戳、时区偏移和时区名称)以进行正确检索 - 请参阅“类型时间”作为答案。
让您的操作系统、数据库和应用程序 tzdata 文件在它们自己和世界其他地方之间保持同步。
在服务器上,将硬件时钟和操作系统时钟设置为 UTC 而不是本地时区。
无论前面的要点如何,服务器端代码(包括网站)都不应期望服务器的本地时区是特定的。看答案。
在所有服务器上使用 NTP 服务。
如果使用 FAT32,请记住时间戳存储在本地时间,而不是 UTC。
在处理重复性事件(例如每周电视节目)时,请记住时间会随着 DST 的变化而变化,并且会因时区而异。
始终将日期时间值查询为包含下限、不包含上限(>=、