Datetime 夏令时和时区最佳做法

Datetime 夏令时和时区最佳做法,datetime,timezone,utc,dst,datetimeoffset,Datetime,Timezone,Utc,Dst,Datetimeoffset,我希望将这个问题及其答案作为处理夏令时的最终指南,特别是处理实际的转换 如果您有任何补充,请执行 许多系统依赖于保持精确的时间,问题在于夏时制导致的时间变化——将时钟向前或向后移动 例如,在接受订单的系统中,业务规则取决于订单的时间——如果时钟发生变化,则规则可能不那么清晰。订单的时间应如何保持?当然,有无数的场景——这只是一个说明性的场景 你是如何处理夏时制问题的 什么样的假设是解决方案的一部分?(在此处查找上下文) 同样重要的是,如果不是更重要的话: 你试过什么不起作用的 为什么不起作

我希望将这个问题及其答案作为处理夏令时的最终指南,特别是处理实际的转换

如果您有任何补充,请执行

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

例如,在接受订单的系统中,业务规则取决于订单的时间——如果时钟发生变化,则规则可能不那么清晰。订单的时间应如何保持?当然,有无数的场景——这只是一个说明性的场景

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

  • 你试过什么不起作用的
  • 为什么不起作用
我会对编程、操作系统、数据持久性和这个问题的其他相关方面感兴趣


一般答案很好,但我也希望看到细节,特别是当它们仅在一个平台上可用时。

业务规则应该始终有效(除非有法律另有规定)。要知道,公民时间是一团糟的,但它是人们使用的,所以它才是重要的

在内部,将时间戳保存在诸如civil time seconds之类的文件中。这并不特别重要(我赞成),但它确实使事情比另一种更容易。假装不存在,除非你正在做真正需要它们的事情(例如,卫星跟踪)。时间戳和显示时间之间的映射是应用规则的唯一点;规则经常变化(在全球范围内,一年几次;责怪政客),因此您应该确保不硬编码映射。奥尔森的答案非常宝贵。

答案和其他数据摘要:(请添加您的答案) Do:

  • 无论何时,只要你指的是一个精确的时刻,就要根据不受夏令时影响的统一标准来确定时间。(GMT和UTC在这方面是等效的,但最好使用术语UTC。请注意,UTC也称为Zulu或Z时间。)
  • 相反,如果您选择使用本地时间值保留时间,请包含此特定时间相对于UTC的本地时间偏移量(此偏移量可能会在一年中发生变化),以便稍后可以明确解释时间戳
  • 在某些情况下,您可能需要同时存储UTC时间和等效的本地时间。通常这是通过两个单独的字段来完成的,但是一些平台支持一种
    datetimeoffset
    类型,可以将这两个字段都存储在一个字段中
  • 将时间戳存储为数值时,使用-这是自
    1970-01-01T00:00:00Z
    以来的整秒数(不包括闰秒)。如果需要更高的精度,请使用毫秒。此值应始终基于UTC,不进行任何时区调整
  • 如果以后可能需要修改时间戳,请包含原始时区ID,以便确定偏移量是否已从记录的原始值更改
  • 安排未来事件时,通常首选本地时间而不是UTC,因为偏移量通常会发生变化,和
  • 存储完整日期(如生日和周年纪念日)时,不要转换为UTC或任何其他时区。
    • 如果可能,请存储在不包含时间的仅日期数据类型中
    • 如果此类类型不可用,请确保在解释值时始终忽略一天中的时间。如果您不能确定一天中的时间将被忽略,请选择中午12:00,而不是午夜00:00作为该天更安全的代表时间
  • 请记住,时区偏移并不总是小时数的整数(例如,印度标准时间为UTC+05:30,尼泊尔使用UTC+05:45)
  • 如果使用Java,请使用Java 8及更高版本。
    • 大部分java.time功能都在库中向后移植到Java6和Java7
    • 在库中进一步适应早期Android(<26)
    • 这些项目正式取代了现在的老项目。Joda Time、Three Ten Backport、java.Time类和由同一人领导
  • 如果使用,考虑使用.
  • 如果没有NoDA时间使用.NET,则认为 DeTeMeOffels通常比 > DATEIME/<代码>更好。
  • 如果使用Perl,请使用
  • 如果使用Python,请使用或
  • 如果使用JavaScript,请与扩展一起使用
  • 如果使用PHP>5.2,请使用
    DateTime
    DateTimeZone
    类提供的本机时区转换。使用
    DateTimeZone::ListAbstraints()时要小心。要使PHP保持最新的Olson数据,请定期安装PECL package
    
  • 如果使用C++,请确保使用一个使用正确实现的库。这些包括,和。
    • 请勿用于时区转换。虽然声称支持标准IANA(又名“zoneinfo”)标识符,但它支持POSIX风格的数据,而不考虑每个区域可能已经发生的丰富变化历史。(此外,该文件已无法维护。)
  • 如果使用铁锈,请使用
  • 大多数业务规则使用民用时间,而不是UTC或GMT。因此,在应用应用程序逻辑之前,计划将UTC时间戳转换为本地时区
  • 请记住,时区和偏移量不是固定的,可能会发生变化。例如,历史上,美国和英国使用相同的日期来“向前冲”和“向后退”。然而,在2007年,美国改变了时钟的更换日期。这就意味着一年中的48周内
    SELECT DATEADD('m', SUM(OffsetMinutes), @inputdatetime) AS LocalDateTime
    FROM   TZOffsets
    WHERE  StartDateTime <= @inputdatetime
           AND RegionClassId = @RegionClassId;
    
    SUN 23:00 in Howland Island (-12)
    MON 11:00 GMT 
    TUE 00:00 in Tonga (+13)
    
    AST Arab Standard Time     UTC+03
    AST Arabian Standard Time  UTC+04
    AST Arabic Standard Time   UTC+03
    
     new DateTime(int year, int month, int day, int hour, int minute, TimeZone timezone)
    
    <?php
    $now = new DateTime(null, new DateTimeZone('Europe/Amsterdam'));
    echo $now->getOffset();
    ?>