Windows上的Java时钟精度:15-16ms

时间:2018-04-25 13:08:50

标签: java windows java-time

Windows上的时钟准确性似乎最近有所改变。我记得它自Windows 7(1毫秒分辨率)以来非常准确,现在时间以15到16毫秒的步幅跳跃。我注意到由于一些(尽管写得不好)单元测试失败(测试检查写入和读取记录之间已经过了一段时间)。

这会影响以下实施:

  • LocalDate
  • System.currentTimeMillis()
  • LocalTime.now()
  • LocalDateTime.now()

我很清楚使用ZonedDateTime.now()增量来测量经过的时间,但我还是想知道如果我错过了将时钟分辨率改回15-16ms的东西。

环境:

  • Windows 10版本1709
  • JRE / JDK 1.8.0_171-b11 (64位)

有没有人注意到这一点?这个决议改变的原因是什么?

编辑:
测试代码以检查此行为(请参阅输出:时间更改和更改前的样本数量)

System.nanoTime()

1 个答案:

答案 0 :(得分:0)

为了获得本地时间而不管平台的最佳准确度,我提出了一个基于当前时间(测量时间增加)作为锚点的解决方案,并且基于System.nanoTime()增量的偏移量。

优点:

  • 精确的当前时间不依赖于平台
  • 高精度(纳米时间)
  • 可移植(因为java.time对象实际上可以承载纳秒精度)。

代码(可以根据LocalTimeLocalDateTime进行调整):

/**
 * Exact zoned date/time, compensates for the 15-16ms leaps 
 * of milliseconds time on some Java platforms.
 */
public final class ExactZonedDateTime {

    private static ZonedDateTime anchor;
    private static long anchorNanos;

    static {
        ZonedDateTime last = ZonedDateTime.now();
        while (((anchor = ZonedDateTime.now()).equals(last))) {
            anchorNanos = System.nanoTime();
        }
    }

    private ExactZonedDateTime() {
    }

    public static ZonedDateTime now() {
        return anchor.plusNanos(System.nanoTime() - anchorNanos);
    }
}

后续电话:

  

2018-04-26T12:51:02.293079632 + 02:00 [欧洲/苏黎世]   2018-04-26T12:51:02.293524865 + 02:00 [欧洲/苏黎世]   2018-04-26T12:51:02.293598126 + 02:00 [欧洲/苏黎世]   2018-04-26T12:51:02.293660770 + 02:00 [欧洲/苏黎世]   2018-04-26T12:51:02.293725538 + 02:00 [欧洲/苏黎世]