【问题标题】:Is the value returned by System.currentTimeMillis() affected by Day Light Savings and Leap Second adjustments?System.currentTimeMillis() 返回的值是否受夏令时和闰秒调整的影响?
【发布时间】:2013-09-19 16:06:57
【问题描述】:

我知道System.currentTimeMillis() 给出了自纪元以来的毫秒数,它对系统的挂钟时间很敏感。我也知道在测量时间的程序中使用System.currentTimeMillis() 来计算经过的时间是不可取的。 Java 库为此提供了System.nanoTime()

我有两个具体问题要问System.currentTimeMillis()

  1. 是否会受到闰秒调整的影响?我认为答案是是的,因为系统的挂钟时间会因为闰秒而调整。
  2. DST(夏令时)开启/关闭时会受到影响吗?当时间突然从 23:59 变为 2:00 时会发生什么?由于系统时钟实际上发生了变化,我认为答案再次是,但我想与社区核实。

【问题讨论】:

  • 系统时钟不一定会在 DST 更改时更改。类 Unix 系统通常将其保持在 UTC。
  • @kiheru 那么系统托盘在 DST 触发后不会显示调整后的时间?
  • 用户可见时间发生变化,但硬件时钟时间不变。 currentTimeMillis() on 例如solaris 使用gettimeofday()。那是自纪元以来的时间,与时区无关。我不知道窗户。
  • 可以以令人惊讶的方式更改返回的时间的一件事是由 NTP 守护程序(或手动)完成的时间调整。因此,两个后续currentTimeMillis() 调用的时间差可能为负数。

标签: java datetime time dst


【解决方案1】:

System.currentTimeMillis() 返回的值是自 epoch 以来经过的毫秒数。这个毫秒数就是:毫秒数。

假设在某一天,由于 DST,您所在的国家/地区决定立即从 1:00 变为 2:00。这是否意味着在 1:00 和 2:00 之间已经过去了 1 小时?第 0 毫秒已经过去。您的国家简单地决定毫秒值 X 表示为 1:00,而毫秒 X + 1 表示为 2:00。时间的表示不会改变毫秒。

【讨论】:

  • 不是实际经过的 SI 毫秒数,除非 TAI(或类似的时间刻度)用于 currentTimeMillis()(不太可能)。要获得实际经过的毫秒数,您需要添加事件之间的闰秒数差异。如果你试着找出2012-06-30T23:59:59Z2012-07-01T00:00:00Z之间的区别就特别清楚了——currentTimeMillis()返回1000但实际数字是2000
  • @J.F.Sebastian 好评论,但我会小心使用 1970 年后以这种确切形式已知的术语 TAI - 另请参阅 details。这是基于史蒂夫艾伦的研究工作。 JB Nizet 并没有谈到 SI 秒,只是关于“毫秒”;-)
【解决方案2】:

您的两个问题的明确答案是:不,不。

作为对@ok 关于dst 效果的回答的补充,System.currentTimeMillis() 不计算闰秒。在理论和实践上,它取决于操作系统。由于包含的大多数操作系统和 Java 虚拟机都遵循 POSIX 标准,因此(也由于互操作性和行为兼容性问题)甚至不允许闰秒对System.currentTimeMillis() 产生任何影响。

您还可以通过将 System.currentTimeMillis()(除以 1000)的值与您自己计算的自 1972-01-01T00:00:00 以来经过的 SI 秒数进行比较来轻松验证这一点。现在必须相差 25 秒。

以下讨论的更新:

闰秒对System.currentTimeMillis() 没有长期影响(未计算在内),但可能在短期内。然而我认为这无关紧要,因为这个时间源不是为实现高精度和时间稳定性而设计的。

此时间源的输出甚至会发生长达数分钟的突然变化(例如,如果电脑长时间离线)。如果人们要使用这个时间源并在闰秒期间遇到困难问题,那么他们几乎肯定会在这个时间源与外部时间源(如 NTP 服务器)的任何重新同步期间遇到(更困难的)问题。

【讨论】:

  • 普通 Unix 时间戳可能会由于某些系统上的闰秒而重复。你说currentTimeMillis()不一样(避免任何影响)?
  • @JFSebastian 根据我自己的经验,currentTimeMillis() 不会在闰秒期间自动重复此类时间戳(导致短时间内不同的长值),但操作系统内核会设置计时器很快(非常)返回任意时间。因此,从长远来看,该方法不计算闰秒 - 并且由于与其他类似系统的互操作性而不能计算在内。作为旁注:NTP服务器在闰秒期间重复时间戳 - 基于我自己对 2012-07-01 的观察。
  • 您正在描述配置为 ntp 客户端的 Windows 行为。顺便说一句,您对经过秒数的计算必须包括 TAI 时间(或等效时间)——目前比 UTC 提前 35 秒。 UTC is not very well defined in 1970
  • @J.F.Sebastian 同意,UTC 比例是 1972 年在无线电信号中引入的,所以我使用了两年前的近似值。让我们计算自 1972-01-01 以来的 SI 秒,您会看到 System.currentTimeMillis() 不计算闰秒。非常简单明了。
  • “有任何效果”和“不计入”是不等价的。在闰秒前后,时间戳可能会受到影响,具体取决于系统时钟如何考虑闰秒。
猜你喜欢
  • 2013-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-20
  • 2017-02-10
  • 2021-08-25
  • 1970-01-01
  • 2018-11-02
相关资源
最近更新 更多