在我的 Mac 和 Windows 机器上使用
LocalDateTime
创建新的 LocalDateTime.now()
时,我在我的 Mac 上获得了 6 的纳米精度,在我的 Windows 机器上获得了 3 的纳米精度。两者都在运行jdk-1.8.0-172
。
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);
}
}
另一种选择是插入您自己的
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);
}
}
我不认为你可以获得比你已经得到的精度更高的精度。如果您想降低精度以匹配其他系统的精度,这很简单(当您知道如何做时):
LocalDateTime.now(ZoneId.of("Europe/Berlin")).truncatedTo(ChronoUnit.MILLIS);
您获得的精度取决于硬件、设置、操作系统以及 JVM 与所有这些的集成。众所周知,Mac 通常比 Windows 提供更好的精度(尽管我的印象是,根据 OpenJDK 问题,这只是 Java 9 的情况#JDK‑8068730)。
如果有人对 Java 15 上的
Instant
或 mac
的 ubuntu
精度有同样的问题,我想展示不同之处:
mac即时精度:
2021-03-10T12:28:19.228816Z
ubuntu即时精度:
2021-03-10T12:28:19.228816800Z
解决方案:如果您想在此操作系统上具有相同的精度,请将
.truncatedTo(ChronoUnit.MILLIS)
添加到Instant
变量
您可以使用格式化程序设置精度,而无需诉诸
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"