为什么新的 Java 8 Date Time API 没有纳秒精度?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33477695/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 21:43:51  来源:igfitidea点击:

Why does the new Java 8 Date Time API not have nanosecond precision?

javajava-8java-time

提问by Thomas Oellrich

One of the features of the new Date Time API in Java 8 is supposed to be nanosecond precision. However when I print the current Date Time to the console like so

Java 8 中新的日期时间 API 的特性之一应该是纳秒精度。但是,当我像这样将当前日期时间打印到控制台时

DateTimeFormatter formatter = DateTimeFormatter
    .ofPattern("yyyy-MM-dd'T'HH:mm:ss,nnnnnnnnnZ");
System.out.println(OffsetDateTime.now().format(formatter)); 

I only see millisecond precision: 2015-11-02T12:33:26,746000000+0100

我只看到毫秒精度:2015-11-02T12:33:26,746000000+0100

The operating system does seem to support nanosecond precision. When I print the current date time via the Terminal

操作系统似乎确实支持纳秒精度。当我通过终端打印当前日期时间时

date -Ins

I see 2015-11-02T12:33:26,746134417+0100

我看到 2015-11-02T12:33:26,746134417+0100

How do I get nanosecond precision in Java? I'm running Oracle Java 1.8.0_66 on Ubuntu 14.04 64-bit

如何在 Java 中获得纳秒精度?我在 64 位 Ubuntu 14.04 上运行 Oracle Java 1.8.0_66

回答by Jon Skeet

The java.timeAPI in general doeshave nanosecond precision. For example:

java.time一般的API确实有纳秒的精度。例如:

DateTimeFormatter formatter = DateTimeFormatter
    .ofPattern("yyyy-MM-dd'T'HH:mm:ss,nnnnnnnnnZ");
OffsetDateTime odt = OffsetDateTime.of(2015, 11, 2, 12, 38, 0, 123456789, ZoneOffset.UTC);
System.out.println(odt.format(formatter));

Output:

输出:

2015-11-02T12:38:00,123456789+0000

However, it's the clock value returned by OffsetDateTime.now()which is returning a value which only has milliseconds.

但是,它OffsetDateTime.now()是返回的时钟值,它返回一个只有毫秒的值。

From Clockimplementation in Java 8:

来自ClockJava 8 的实现:

The clock implementation provided here is based on System.currentTimeMillis(). That method provides little to no guarantee about the accuracy of the clock. Applications requiring a more accurate clock must implement this abstract class themselves using a different external clock, such as an NTP server.

此处提供的时钟实现基于System.currentTimeMillis(). 该方法几乎不能保证时钟的准确性。需要更精确时钟的应用程序必须使用不同的外部时钟(例如 NTP 服务器)自己实现这个抽象类。

So there's nothing inherently imprecise here - just the default implementation of Clockusing System.currentTimeMillis(). You could potentially create your own more precise subclass. However, you should note that adding more precision without adding more accuracyprobably isn't terribly useful. (There are times when it might be, admittedly...)

所以这里没有什么本质上不精确的——只是Clockusing的默认实现System.currentTimeMillis()。您可能会创建自己的更精确的子类。但是,您应该注意,在不增加准确性的情况下增加更多的精度可能不是很有用。(诚​​然,有时可能是这样......)

回答by Meno Hochschild

To make an important addition to the answer of Jon Skeet, Java 9 is supposed to deliver a clock in improved precision- see the bug log. Background: On many operating systems (especially Linux), there are better clocks available.

为了对 Jon Skeet 的回答做出重要补充,Java 9 应该提供一个精度更高的时钟- 请参阅错误日志。背景:在许多操作系统(尤其是 Linux)上,有更好的时钟可用。

The Java SE 8 specification for java.time.Clock states that "The system factory methods provide clocks based on the best available
system clock. This may use System.currentTimeMillis(), or a higher resolution clock if one is available.". In JDK 8 the implementation
of the clock returned was based on System.currentTimeMillis(), and thus has only a millisecond resolution. In JDK 9, the implementation
is based on the underlying native clock that System.currentTimeMillis() is using, providing the maximum resolution available from that clock. On most systems this can be microseconds, or sometimes even tenth of microseconds.

An application making the assumption that the clock returned by these system factory methods will always have milliseconds precision and actively depends on it, may therefore need to be updated in order to take into account the possibility of a greater resolution, as was
stated in the API documentation.

java.time.Clock 的 Java SE 8 规范声明“系统工厂方法提供基于最佳可用
系统时钟的时钟。这可以使用 System.currentTimeMillis(),或者如果可用,则使用更高分辨率的时钟。”。在 JDK 8
中,返回时钟的实现基于 System.currentTimeMillis(),因此只有毫秒分辨率。在 JDK 9 中,实现
基于 System.currentTimeMillis() 使用的底层本机时钟,提供该时钟可用的最大分辨率。在大多数系统上,这可能是微秒,有时甚至是十分之一微秒。

假设这些系统工厂方法返回的时钟始终具有毫秒精度并积极依赖它的应用程序,因此可能需要更新以考虑更高分辨率的可能性,如
API 中所述文档。

It should also be noted the (exotic) fact that second precision will not exist near leap seconds - not even in Java 9.

还应该注意一个(奇异的)事实,即在闰秒附近不存在秒精度——即使在 Java 9 中也不存在。