Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows上的Java时钟精度:15-16ms_Java_Windows_Java Time - Fatal编程技术网

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

Windows上的Java时钟精度:15-16ms,java,windows,java-time,Java,Windows,Java Time,Windows上的时钟精度最近似乎发生了变化。我记得自从Windows 7(1毫秒分辨率)以来,它非常准确,现在时间以15到16毫秒的步长跳跃。我注意到,由于一些单元测试失败(尽管写得很糟糕)(测试检查了写入和读取记录之间经过的时间) 这会影响以下实现: System.currentTimeMillis() LocalTime.now() LocalDateTime.now() ZoneDateTime.now() 我很清楚,要使用System.nanoTime()delta来测量经过的时间

Windows上的时钟精度最近似乎发生了变化。我记得自从Windows 7(1毫秒分辨率)以来,它非常准确,现在时间以15到16毫秒的步长跳跃。我注意到,由于一些单元测试失败(尽管写得很糟糕)(测试检查了写入和读取记录之间经过的时间)

这会影响以下实现:

  • System.currentTimeMillis()
  • LocalTime.now()
  • LocalDateTime.now()
  • ZoneDateTime.now()
我很清楚,要使用
System.nanoTime()
delta来测量经过的时间,但我想知道是否错过了将时钟分辨率改回15-16ms的内容

环境:

  • Windows10版本1709
  • JRE/JDK1.8.0_171-b11(64位)
有人也注意到了吗?此决议更改的原因可能是什么

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

@测试
公共无效testCurrentTimeMillis(){
测试(()->System.currentTimeMillis());
}
@试验
公共void testNanoTime(){
测试(()->System.nanoTime());
}
@试验
public void testLocalTime(){
test(()->LocalTime.now());
}
@试验
public void testLocalDateTime(){
test(()->LocalDateTime.now());
}
@试验
公共无效TestZoneDateTime(){
测试(()->ZoneDateTime.now());
}
专用无效测试(供应商时间供应商){
int样本=20;
字符串lastTimeString=null;
整数计数=0;
而(样本数>0){
计数++;
String timeString=timeSupplier.get().toString();
如果(!timeString.equals(lastTimeString)){
System.out.println(timeString+“(“+count+”));
lastTimeString=timeString;
计数=0;
样本--;
}
}
}

为了在不考虑平台的情况下以最佳精度获得本地时间,我提出了一个解决方案,它基于当前时间(增加时测量)作为锚定,并基于
System.nanoTime()
增量进行偏移

优点:

  • 精度不取决于平台的当前时间
  • 高精度(纳米时间)
  • 可移植(正如
    java.time
    对象实际上可以携带纳秒精度)
代码(也可以调整为服务于LocalTimeLocalDateTime):

后续电话:

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[欧洲/苏黎世]


你打开了windows开发者模式吗?@ShanuGupta:没有,它关闭了(在“侧载应用程序”中),你能打开并再次检查吗?您可能必须重新启动系统。可能与@OleV.V重复。另一个问题可以追溯到2009年,当时这种错误在32位Windows平台上很常见。我的案例是最近的一个64位Windows平台,问题再次出现。
@Test
public void testCurrentTimeMillis() {
    test(() -> System.currentTimeMillis());
}

@Test
public void testNanoTime() {
    test(() -> System.nanoTime());
}

@Test
public void testLocalTime() {
    test(() -> LocalTime.now());
}

@Test
public void testLocalDateTime() {
    test(() -> LocalDateTime.now());
}

@Test
public void testZonedDateTime() {
    test(() -> ZonedDateTime.now());
}

private <T> void test(Supplier<T> timeSupplier) {

    int samples = 20;
    String lastTimeString = null;
    int count = 0;
    while (samples > 0) {

        count++;
        String timeString = timeSupplier.get().toString();
        if (!timeString.equals(lastTimeString)) {
            System.out.println(timeString + " (" + count + ")");
            lastTimeString = timeString;
            count = 0;
            samples--;
        }
    }
}
/**
 * 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);
    }
}