2015-11-02 13 views
66

Una delle funzionalità della nuova API Date Time in Java 8 dovrebbe essere la precisione di un nanosecondo. Tuttavia quando ho stampare la data corrente ora alla console in questo modoPerché la nuova API Java 8 Date Time non ha una precisione di nanosecondi?

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

vedo solo millisecondo di precisione: 2015-11-02T12: 33: 26,746000000 + 0100

Il sistema operativo non sembra supportare precisione al nanosecondo. Quando stampo l'ora data corrente tramite il terminale

date -Ins 

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

Come faccio ad avere la precisione nanosecondo in Java? Sto eseguendo Oracle Java 1.8.0_66 su Ubuntu 14.04 64-bit

+1

rimediato in Java 9. [Un'implementazione fresco] (https: // bugs.openjdk.java.net/browse/JDK-8068730) di ['Clock'] (https://docs.oracle.com/javase/8/docs/api/java/time/Clock.html) cattura l'attuale momento fino a una risoluzione di nanosecondi (a seconda della capacità dell'orologio hardware dell'host). –

risposta

101

L'API java.time in generale ha con precisione in nanosecondi. Per esempio:

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

uscita:

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

Tuttavia, è il valore restituito da orologio OffsetDateTime.now() che sta restituendo un valore che ha solo millisecondi.

Da Clock implementazione in Java 8:

L'implementazione orologio qui fornite si basa su System.currentTimeMillis(). Questo metodo fornisce poca o nessuna garanzia circa la precisione dell'orologio. Le applicazioni che richiedono un clock più preciso devono implementare questa classe astratta utilizzando un clock esterno diverso, ad esempio un server NTP.

Quindi non c'è nulla di intrinsecamente impreciso qui - solo l'implementazione predefinita di Clock usando System.currentTimeMillis(). Potresti potenzialmente creare la tua sottoclasse più precisa. Tuttavia, dovresti notare che aggiungere più precisione senza aggiungere altro precisione probabilmente non è molto utile. (Ci sono momenti in cui potrebbe essere, è vero ...)

+7

Quest'ultimo bit è particolarmente importante. ['nanosleep (2)'] (http://linux.die.net/man/2/nanosleep) ha problemi simili su hardware standard, di tipo consumer, poiché dormire per un numero preciso di nanosecondi comporta una barra di errore di ~ 1 Ciclo della CPU, che non può davvero essere fatto in un ambiente multitasking preventivamente. Tuttavia, alti livelli di precisione possono essere utili se avete solo bisogno di ordinare vari eventi uno rispetto all'altro e non preoccupatevi degli intervalli precisi tra loro. Suppongo che l'orologio stia aumentando monotonicamente, che io * spero * sia vero. – Kevin

51

Per fare un'aggiunta importante per la risposta di Jon Skeet, Java 9 si suppone per consegnare un orologio in una migliore precisione - vedi the bug log. Background: su molti sistemi operativi (specialmente Linux), sono disponibili migliori orologi.

Java specifica SE 8 per java.time.Clock afferma che "I metodi di fabbrica del sistema forniscono orologi sulla base della miglior orologio
sistema disponibile. Questo può utilizzare System.currentTimeMillis(), o un più alto orologio di risoluzione se disponibile ". In JDK 8 l'implementazione dell'orologio restituito era basata su System.currentTimeMillis() e ha quindi solo una risoluzione di millisecondo. In JDK 9, l'implementazione
si basa sul clock nativo sottostante utilizzato da System.currentTimeMillis(), che fornisce la risoluzione massima disponibile da quell'orologio.Sulla maggior parte dei sistemi questo può essere microsecondi, o talvolta anche decimo di microsecondi.

Un'applicazione facendo l'ipotesi che l'orologio restituito da questi metodi di fabbrica sistema avrà sempre millisecondi precisione e dipende attivamente su di esso, può quindi bisogno di essere aggiornato al fine di prendere in considerazione la possibilità di una maggiore risoluzione , come lo era
indicato nella documentazione API.

Si deve anche notare la (esotici) fatto che secondo la precisione non esisterà vicino secondo salto - nemmeno in Java 9.

+0

Esistono ulteriori informazioni sul motivo per cui la seconda precisione non esiste nei pressi di secondi bisestili? È perché ci sono [molteplici modi per implementarli] (https://en.wikipedia.org/wiki/Leap_second#Workarounds_for_leap_second_issues) (ad esempio, sbavature)? – Thunderforge

+5

@Thunderforge Un'espressione come 'ChronoUnit.SECONDS.between (instant1, instant2)' non può mai contare secondi bisestili. 'I progettisti di java.time' hanno deciso di nascondere il secondo di salto e di fingere che ogni minuto sia composto da 60 secondi. Le loro specifiche impongono ufficialmente l'UTC-SLS e la reale implementazione in JDK è de facto come POSIX, non come l'UTC-SLS, semplicemente ignorando i secondi bisestili. Tutti gli orologi del SO noti (come base di 'Clock.systemUTC()' si comportano allo stesso modo o applicano qualche tipo di reset dell'orologio o sbavatura di sec di salto. SI-secs non sono modellati.Se si cerca seriamente il supporto del vero leap sec allora si consideri il mio lib Time4J. –

Problemi correlati