来自Joda Time 常见问题解答:
是否支持闰秒?
Joda-Time 不支持闰秒。可以通过编写一个新的、专门的年表来支持闰秒,或者对现有的ZonedChronology
类进行一些增强。在任何一种情况下,未来版本的 Joda-Time 都不会默认启用闰秒。大多数应用程序都不需要它,而且它可能会产生额外的性能成本。
来自闰秒的 IANA/Olson TZDB 文件:
尽管该定义还包括减少秒数(“负”闰秒)的可能性,但这从未发生过,并且在可预见的将来不太可能是必需的。
你的第一个问题:
如何确保 ts 总是在增加而不是向后?
一个负闰秒将使您处于相同的时间戳(两个经过秒的一个值),因此如果没有两个负闰秒,您就无法真正向后退。由于似乎不太可能出现负闰秒,我会说这是你永远不会真正遇到的问题。
更新:我可以设想时间戳倒退的唯一方法是,如果您使用毫秒精度并遇到下面的行为 #3。
你的第二个问题:
如何从考虑到闰秒的 db 中准确选择 100 秒间隔?
由于您以 UTC 记录时间,因此您的值已经包含闰秒。我知道这听起来可能违反直觉,因为正如您所描述的那样,一天中正好有 86400 秒(86400000 毫秒)。但他们确实在那里。如果他们不是 - 那么我们将与 TAI 同步,而不是 UTC。那怎么可能呢?好吧,当闰秒发生时,可能会发生一些不同的事情:
如果操作系统和应用程序代码都支持闰秒,那么它确实可以将显示秒显示为:60
或:61
。但是几乎没有真正的实现,因为编程语言通常只允许几秒钟的时间去:59
.
操作系统可能会“冻结”一秒钟,并在一整秒内给出相同的值。
操作系统可能会前进到:59.999
,然后跳回到:59.000
以重复闰秒所覆盖的时间段。(感谢@Teo)
操作系统可能会“漂移”或“拖尾”一段时间,一次缓慢地将系统时钟增加几毫秒,直到它完全赶上额外的一秒。
操作系统可能会跳过它并且什么也不做。您的时钟将不同步,直到下一次通过 NTP 同步。如果它恰好在闰秒的那一刻同步,它可能只是将时间设置为:59
或:00
再次不同步一段时间。
让我们考虑一个真实的例子。该值1341100800000
代表 2012 年 7 月 1 日,恰好在 UTC 午夜。(您可以在此网站上查看它,或者在您的 Java 或 Joda 时间代码中进行验证。)如果我们除以 86400000,我们将得到自 1970 年 1 月 1日以来经过的 15522 天 UTC 。
该值包括35 个闰秒,包括 2012 年 6 月 30 日结束前一秒发生的闰秒。就好像闰秒根本没有发生。
所以大多数时候,你不需要担心闰秒。假装它们不存在。让您的操作系统以它想要的任何方式处理它们。
如果您需要超精确的时间测量,也许是在科学环境中,那么您无论如何都不应该使用计算机的系统时钟。除了可以保持、延长或忽略闰秒这一事实之外,它的设计并不是为了像计时器那样精确。相反,您可能应该使用一些非常专业的计时硬件,例如该供应商提供的那些。
更新:如果您正在快速记录事件(每秒许多事件),并且您的操作系统具有上述#3 中描述的行为,您可能需要处理闰秒。在这种情况下,我的建议是不要按时间戳排序,而是考虑保留一个单独的单调递增序列号,然后按此排序。
例如,您的数据库中可能已经有一个自动递增的整数 ID。您仍然可以在 where 子句中按时间戳进行过滤以获取特定日期的数据,但是您将按 ID 排序,以便事件按顺序排列,即使时间戳不是。
有关其他建议,请参阅Teo 的回答。