LocalDateTime.now() 在 Windows 和 Mac 机器上具有不同级别的精度

问题描述 投票:0回答:4

在我的 Mac 和 Windows 机器上使用

LocalDateTime
创建新的
LocalDateTime.now()
时,我在我的 Mac 上获得了 6 的纳米精度,在我的 Windows 机器上获得了 3 的纳米精度。两者都在运行
jdk-1.8.0-172

  • 是否有可能限制或提高其中一个的精度 机器?
  • 为什么精度实际上不同?
java precision java-time platform
4个回答
32
投票

精度不同因为

LocalDateTime.now()
使用系统默认
Clock
.

从默认时区的系统时钟获取当前日期时间。

这将在默认时区查询系统时钟以获取当前日期时间。

...

此 Javadoc 中的链接将带您到

Clock.systemDefaultZone()
其中指出(强调 我的):

使用最佳可用系统时钟获取返回当前时刻的时钟,使用默认时区转换为日期和时间。

此时钟基于可用的最佳系统时钟。 这可能会使用 System.currentTimeMillis(),或者更高分辨率的时钟(如果可用的话)。

...

Java 使用哪个时钟取决于很多因素,看起来您的 Mac 计算机的时钟精度为 microsecond,而您的 Windows 计算机的时钟精度为 millisecond。我不知道有什么方法可以 increase 时钟的精度,但你绝对可以 decrease 精度,以便它跨平台匹配。

一个选择是使用

LocalDateTime.truncatedTo(TemporalUnit)

import java.time.Instant;
import java.time.temporal.ChronoUnit;

public class Main {

  public static void main(String[] args) {
    Instant original = Instant.now();
    System.out.printf("Original instant  : %s%n", original);

    Instant truncated = original.truncatedTo(ChronoUnit.MILLIS);
    System.out.printf("Truncated instant : %s%n", truncated);
  }
}

-另见 Ole V.V. 的回答

另一种选择是插入您自己的

Clock
并使用
LocalDateTime.now(Clock)
。如果可能的话,我会使用
Clock.tickMillis(ZoneId)
因为这个方法返回一个截断到毫秒的
Clock

获得一个时钟,该时钟使用最佳可用系统时钟以整毫秒返回当前的即时滴答声。

此时钟将始终将纳秒级字段截断为毫秒。这确保可见时间以整毫秒计。底层时钟是最好的可用系统时钟,相当于使用 system(ZoneId)。

...

自:
9

例如:

import java.time.Clock;
// import java.time.Duration;
import java.time.Instant;
import java.time.ZoneId;

public class Main {

  public static void main(String[] args) {
    // Java 8
    // Clock clock = Clock.tick(Clock.systemDefaultZone(), Duration.ofMillis(1));

    // Java 9+
    Clock clock = Clock.tickMillis(ZoneId.systemDefault());

    Instant instant = Instant.now(clock);
    System.out.printf("Instant : %s%n", instant);
  }
}

12
投票

我不认为你可以获得比你已经得到的精度更高的精度。如果您想降低精度以匹配其他系统的精度,这很简单(当您知道如何做时):

LocalDateTime.now(ZoneId.of("Europe/Berlin")).truncatedTo(ChronoUnit.MILLIS);

您获得的精度取决于硬件、设置、操作系统以及 JVM 与所有这些的集成。众所周知,Mac 通常比 Windows 提供更好的精度(尽管我的印象是,根据 OpenJDK 问题,这只是 Java 9 的情况#JDK‑8068730)。


8
投票

如果有人对 Java 15 上的

Instant
mac
ubuntu
精度有同样的问题,我想展示不同之处:

mac即时精度:

2021-03-10T12:28:19.228816Z

ubuntu即时精度:

2021-03-10T12:28:19.228816800Z

解决方案:如果您想在此操作系统上具有相同的精度,请将

.truncatedTo(ChronoUnit.MILLIS)
添加到
Instant
变量


0
投票

您可以使用格式化程序设置精度,而无需诉诸

truncatedTo
Clock.tickMillis

jshell> OffsetDateTime.now().format(ISO_DATE_TIME)
$5 ==> "2020-10-21T10:13:48.57776451+02:00"

jshell> OffsetDateTime.now().format(ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSZ"))
$8 ==> "2020-10-21T10:15:31.27+0200"

我发现JDK 15在macOS和Linux上有不同的精度后才意识到这一点

© www.soinside.com 2019 - 2024. All rights reserved.