web-dev-qa-db-ja.com

新しいJava 8 Date Time APIにナノ秒の精度がないのはなぜですか?

Java 8の新しいDate Time APIの機能の1つは、ナノ秒の精度であることが想定されています。ただし、現在のDate Timeをコンソールに出力する場合

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

ミリ秒の精度しか表示されません:2015-11-02T12:33:26,746000000 + 0100

オペレーティングシステムはナノ秒の精度をサポートしているようです。ターミナル経由で現在の日付時刻を印刷するとき

date -Ins

2015-11-02T12:33:26,746134417 + 0100が表示されます

Javaでナノ秒の精度を得るにはどうすればよいですか? Ubuntu 14.04 64ビットでOracle Java 1.8.0_66を実行しています

71
Thomas Oellrich

一般に_Java.time_ APIdoesはナノ秒の精度を持ちます。例えば:

_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));
_

出力:

_2015-11-02T12:38:00,123456789+0000
_

ただし、ミリ秒のみの値を返すのは、OffsetDateTime.now()によって返されるクロック値です。

Clock の実装Java 8:

ここで提供されるクロックの実装は、System.currentTimeMillis()に基づいています。この方法では、クロックの精度についてほとんどまたはまったく保証されません。より正確なクロックを必要とするアプリケーションは、NTPサーバーなどの別の外部クロックを使用して、この抽象クラス自体を実装する必要があります。

したがって、本質的に不正確なものは何もありません-System.currentTimeMillis()を使用したClockのデフォルト実装だけです。独自のより正確なサブクラスを作成できる可能性があります。ただし、さらにaccuracyを追加せずに精度を追加することはおそらくあまり役​​に立たないことに注意してください。 (確かにそうなる場合もあります...)

105
Jon Skeet

Jon Skeetの答えに重要な追加を加えるために、Java 9は改善された精度でクロックを配信することになっています- バグログ 。背景:多くのオペレーティングシステム(特にLinux)では、より良いクロックが利用可能です。

Java.time.ClockのJava SE 8仕様は、「システムファクトリメソッドは利用可能な最適なクロックを提供します
システムクロック。これは、System.currentTimeMillis()、または使用可能な場合はより高解像度のクロックを使用する場合があります。」JDK 8では実装
返されたクロックはSystem.currentTimeMillis()に基づいていたため、ミリ秒の分解能しかありません。 JDK 9では、実装
は、System.currentTimeMillis()が使用している基礎となるネイティブクロックに基づいており、そのクロックから利用可能な最大解像度を提供します。ほとんどのシステムでは、これはマイクロ秒、場合によっては10分の1マイクロ秒にもなります。

これらのシステムファクトリメソッドによって返されるクロックは常にミリ秒の精度を持ち、それに積極的に依存することを前提とするアプリケーションは、より高い解像度の可能性を考慮するために更新する必要がありました。
APIドキュメントに記載されています。

また、うるう秒の近くに秒精度が存在しないという(エキゾチックな)事実-Java 9。

55
Meno Hochschild