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

Java LocalDateTime.now()在Windows和Mac计算机上具有不同的精度级别,java,precision,java-time,platform,Java,Precision,Java Time,Platform,在我的Mac和Windows机器上使用LocalDateTime.now()创建新的LocalDateTime时,我的Mac电脑上的nano精度为6,Windows机器上的nano精度为3。两者都在运行jdk-1.8.0-172 是否有可能限制或提高其中一个传感器的精度 机器 为什么精度实际上不同呢 我认为你无法获得比你已经获得的精度更好的精度。如果您想降低精度以匹配其他系统的精度,那么很简单(如果您知道如何实现): 获得的精度取决于硬件、设置、操作系统以及JVM与所有这些的集成。众所周知,M

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

  • 是否有可能限制或提高其中一个传感器的精度 机器
  • 为什么精度实际上不同呢

我认为你无法获得比你已经获得的精度更好的精度。如果您想降低精度以匹配其他系统的精度,那么很简单(如果您知道如何实现):


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

精度不同,因为使用了系统默认值

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

这将查询默认时区中的,以获取当前日期时间

这个Javadoc中的链接将带您到
Clock.systemDefaultZone()
,其中说明(emphasis我的):

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

此时钟基于最佳可用系统时钟这可能会使用或使用更高分辨率的时钟(如果有)。

Java使用哪种时钟取决于很多因素,看起来Mac电脑的时钟精度为微秒,而Windows电脑的时钟精度为毫秒。我不知道有什么方法可以提高时钟的精度,但是你可以降低精度,这样它就可以跨平台匹配

一个选择是按需操作和使用

另一个选择是插入自己的
时钟
并使用。如果可能,我会使用,因为此方法返回一个截断为毫秒的
时钟

获取一个时钟,该时钟使用最佳可用系统时钟以整毫秒为单位返回当前即时滴答声

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

自:
九,


您可以使用格式化程序设置精度,而无需求助于
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"

我在发现后意识到了这一点。

如果有人在
mac
或Java 15上的
ubuntu
Instant
精度方面有相同的问题,我想展示一下区别:

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

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


解决方案:如果希望在该操作系统上具有相同的精度,请将
.truncatedTo(ChronoUnit.MILLIS)
添加到
Instant
变量中

使用,这意味着无论系统时钟具有何种精度,都是
LocalDateTime.now()的精度。“毫秒精度为6”这和微秒精度一样吗?(也许更好的说法是“亚秒精度”)。对不起!它实际上被称为“nano”。@Slaw运行
System.currentTimeMillis()
在两台机器上提供相同的精度。系统
时钟可以使用
System.currentTimeMillis()
或更高分辨率的时钟(如果可用)。你的Mac电脑似乎有一个微秒级的时钟。需要ZoneID吗?“也许有点让人困惑,至少这是一种隐藏重要部分(笔记本电脑)的好习惯,如果你想控制你所得到的,”CarlosHeuberger说。如果您希望JVM的默认时区在那一刻出现,我仍然更喜欢
ZoneId.systemDefault()
而不是忽略它。虽然结果是一样的,但它更清楚地解读了意图。你是对的,这次讨论与问题无关。当然,有很多“好习惯”。。。像这样的常数?比如避免太长的行?换句话说,当前时刻的解决方案是一个实现细节。
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"