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

LocalDateTime.now() has different levels of precision on Windows and Mac machine

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

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

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

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

精度不同因为LocalDateTime.now() uses a system default Clock.

Obtains the current date-time from the system clock in the default time-zone.

This will query the system clock in the default time-zone to obtain the current date-time.

...

此 Java 文档中的 link 会将您带到 Clock.systemDefaultZone(),其中指出(强调 我的):

Obtains a clock that returns the current instant using the best available system clock, converting to date and time using the default time-zone.

This clock is based on the best available system clock. This may use System.currentTimeMillis(), or a higher resolution clock if one is available.

...

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

一种选择是按照 and use LocalDateTime.truncatedTo(TemporalUnit)

另一种选择是插入您自己的 Clock 并使用 LocalDateTime.now(Clock). If possible, I would use Clock.tickMillis(ZoneId),因为此方法 returns 一个 Clock 截断到毫秒。

Obtains a clock that returns the current instant ticking in whole milliseconds using the best available system clock.

This clock will always have the nano-of-second field truncated to milliseconds. This ensures that the visible time ticks in whole milliseconds. The underlying clock is the best available system clock, equivalent to using system(ZoneId).

...

Since:
9

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

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

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

发现JDK 15 has different precision on macOS and Linux后才意识到这一点。

如果有人对 mac 上的 Instant 精度或 Java 15 上的 ubuntu 精度有同样的问题,我想说明一下区别:

mac即时精度:2021-03-10T12:28:19.228816Z

ubuntu即时精度:2021-03-10T12:28:19.228816800Z

解决方法:如果你想在这个 OS

上有相同的精度,请将 .truncatedTo(ChronoUnit.MILLIS) 添加到 Instant 变量