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