web-dev-qa-db-fra.com

Pourquoi la nouvelle API Java 8 Date Time API n'a-t-elle pas une précision en nanosecondes?

L'une des fonctionnalités de la nouvelle API Date Time en Java 8 est censée être une précision en nanosecondes. Cependant, lorsque j'imprime l'heure actuelle sur la console comme ceci

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

Je ne vois que la précision en millisecondes: 2015-11-02T12: 33: 26,746000000 + 0100

Le système d'exploitation semble prendre en charge la précision en nanosecondes. Lorsque j'imprime la date actuelle via le terminal

date -Ins

Je vois 2015-11-02T12: 33: 26,746134417 + 0100

Comment obtenir une précision en nanosecondes en Java? J'utilise Oracle Java 1.8.0_66 sur Ubuntu 14.04 64 bits

71
Thomas Oellrich

L'API Java.time En général a une précision en nanosecondes. Par exemple:

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

Sortie:

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

Cependant, c'est la valeur d'horloge renvoyée par OffsetDateTime.now() qui renvoie une valeur qui n'a que des millisecondes.

De Clock implémentation dans Java 8:

L'implémentation d'horloge fournie ici est basée sur System.currentTimeMillis(). Cette méthode fournit peu ou pas de garantie sur la précision de l'horloge. Les applications nécessitant une horloge plus précise doivent implémenter cette classe abstraite elles-mêmes en utilisant une horloge externe différente, telle qu'un serveur NTP.

Il n'y a donc rien d'imprécis en soi ici - juste l'implémentation par défaut de Clock en utilisant System.currentTimeMillis(). Vous pouvez potentiellement créer votre propre sous-classe plus précise. Cependant, vous devez noter que l'ajout de plus de précision sans ajouter plus de précision n'est probablement pas très utile. (Il y a des moments où ça pourrait être, certes ...)

105
Jon Skeet

Pour apporter un ajout important à la réponse de Jon Skeet, Java 9 est censé fournir une horloge avec une précision améliorée - voir le journal des bogues . Contexte: Sur de nombreux systèmes d'exploitation (en particulier Linux), de meilleures horloges sont disponibles.

La spécification Java SE 8 pour Java.time.Clock indique que "les méthodes d'usine du système fournissent des horloges basées sur les meilleures
horloge système. Cela peut utiliser System.currentTimeMillis (), ou une horloge de résolution supérieure si elle est disponible. ". Dans JDK 8, l'implémentation
de l'horloge renvoyée était basé sur System.currentTimeMillis (), et n'a donc qu'une résolution en millisecondes. Dans JDK 9, l'implémentation
est basé sur l'horloge native sous-jacente utilisée par System.currentTimeMillis (), fournissant la résolution maximale disponible à partir de cette horloge. Sur la plupart des systèmes, cela peut être en microsecondes, voire parfois au dixième de microsecondes.

Une application supposant que l'horloge renvoyée par ces méthodes d'usine du système aura toujours une précision de quelques millisecondes et en dépend activement, devra donc être mise à jour afin de prendre en compte la possibilité d'une résolution plus élevée, comme cela a été
indiqué dans la documentation de l'API.

Il convient également de noter le fait (exotique) que la seconde précision n'existera pas près des secondes intercalaires - même pas en Java 9.

55
Meno Hochschild