System.currentTimeMillis () restituisce l'ora UTC?


93

Voglio ottenere l'ora UTC corrente in millisecondi. Ho cercato su Google e ho ottenuto alcune risposte che System.currentTimeMillis () restituisce l'ora UTC. ma non è così. Se faccio quanto segue:

long t1 = System.currentTimeMillis();
long t2 = new Date().getTime();
long t3 = Calendar.getInstance().getTimeInMillis();

tutti e tre i tempi sono quasi uguali (la differenza è in milli secondi a causa delle chiamate).

t1 = 1372060916
t2 = 1372060917
t3 = 1372060918

e questa volta non è l'ora UTC, invece è l'ora del mio fuso orario. Come posso ottenere l'ora UTC corrente in Android?


4
Restituisce l'ora di sistema corrente in millisecondi dal 1 gennaio 1970 00:00:00 UTC
Blackbelt


3
lungo t3 = Calendar.getInstance (TimeZone.getTimeZone ("UTC")). getTimeInMillis ();
Blackbelt

3
Il collegamento sopra dice "Vedere la descrizione della classe Date per una discussione sulle lievi discrepanze che possono sorgere tra" l'ora del computer "e l'ora universale coordinata (UTC)." e nella documentazione java.util.Date trovi: "Sebbene la classe Date sia intesa per riflettere l'ora universale coordinata (UTC), potrebbe non farlo esattamente, a seconda dell'ambiente host della Java Virtual Machine" -> quindi potrebbe è possibile che la tua macchina restituisca l'ora non UTC
Marco Forberg

4
@ g.revolution: è "il numero di millisecondi dal 1 gennaio 1970 00:00:00 UTC" - come ti aspetteresti che si aggiusti per un fuso orario? Il fuso orario locale non influisce sul numero di millisecondi trascorsi da quell'epoca.
Jon Skeet

Risposte:


132

Tutte e tre le linee che hai mostrato forniranno il numero di millisecondi trascorsi dall'epoca unix, che è un punto fisso nel tempo, non influenzato dal tuo fuso orario locale.

Dici "questa volta non è l'ora UTC" - sospetto che tu l'abbia effettivamente diagnosticato in modo errato. Suggerirei di utilizzare epochconverter.com per questo. Ad esempio, nel tuo esempio:

1372060916 = Mon, 24 Jun 2013 08:01:56 GMT

Non sappiamo quando hai generato quel valore, ma a meno che non fosse effettivamente alle 8:01 UTC, è un problema con l'orologio di sistema.

System.currentTimeMillisné il valore all'interno di a Datesono influenzati dal fuso orario. Tuttavia, si deve essere consapevoli che Date.toString() non utilizzano il fuso orario locale, che inganna molti sviluppatori a pensare che una Dateè intrinsecamente associato con un fuso orario - non è, è solo un istante nel tempo, senza un fuso orario associato o di un sistema di calendario dispari.


6
Quindi, in pratica, vale a dire che questa funzione restituisce lo stesso valore se chiamata contemporaneamente da fusi orari diversi, indipendentemente dall'orologio dell'host, corretto?
Phillip

14
Amico, questo mi fa desiderare che il mondo (potrebbe) adottare un unico fuso orario. A chi importa se il numero sull'orologio è 00:00 o 08:00 quando la grande cosa luminosa appare nel cielo? Le innumerevoli ore di tempo altrimenti produttivo sprecate su questa reliquia storica mi fanno ribollire il sangue ...
corsiKa

In relazione a ciò, si noti che la chiamata sottostante alla funzione orologio del sistema operativo ha una "deriva" documentata di diversi millisecondi. Java ha un "timer ad alte prestazioni" se l'intenzione è di ottenere una durata altamente precisa di un'operazione (tempistica quando un'attività inizia e finisce, il delta è la quantità di tempo trascorso). Vedi: docs.oracle.com/javase/7/docs/api/java/lang/…
Darrell Teague

@JonSkeet se toString () usa internamente il fuso orario come potrei costruire una stringa da esso senza fuso orario. In realtà sto generando un file nel server REST il cui nome file corrisponde esattamente al valore di mezzanotte ex "1551139200.json" (26 febbraio 2019 00:00:00) e che deve essere accessibile dall'app Android una volta che il dispositivo System.currentTimeMillis () restituisce l'ora esatta.
kiranking

@kiranking: utilizzare Date.getTime()per trovare il tempo in millisecondi dall'epoca di Unix, dividere per 1000 (poiché il nome del file è in secondi dall'epoca di Unix) e formattare semplicemente quel numero intero come stringa.
Jon Skeet,

3

Posso confermare che tutte e tre le chiamate potrebbero dipendere dall'ora locale, considerata l'epoca, non da Date.toString()un metodo simile. Li ho visti dipendere dall'ora locale in dispositivi specifici con Android 2.3. Non li ho testati con altri dispositivi e versioni di Android. In questo caso, l'ora locale è stata impostata manualmente.

L'unico modo affidabile per ottenere un'ora UTC indipendente è richiedere un aggiornamento della posizione utilizzando l'estensione GPS_PROVIDER. Il getTime()valore di una posizione recuperata da NETWORK_PROVIDERdipende anche dall'ora locale. Un'altra opzione è eseguire il ping di un server che restituisce un timestamp UTC, ad esempio.

Quindi, quello che faccio è il seguente:

public static String getUTCstring(Location location) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
    String date = sdf.format(new Date(location.getTime()));
    // Append the string "UTC" to the date
    if(!date.contains("UTC")) {
        date += " UTC";
    }
    return date;
}

1
System.currentTimeMillis () restituisce un valore basato su UTC. Per quanto riguarda la 'precisione' o accuratezza dell'orologio del sistema operativo, anche se certamente questo influisce sul risultato, non è in alcun modo correlato al valore del fuso orario del sistema o dell'ambiente Java.
Darrell Teague

@DarrellTeague Insisto, ho visto valori diversi in uno specifico dispositivo Huawei. Quindi no, non restituisce sempre l'ora UTC corretta (scartando le differenze di precisione)
jlhonora

La domanda dell'OP riguardava l'utilizzo del fuso orario della classe Java. Non si trattava di hardware o dell'accuratezza del valore temporale restituito. In poche parole, la JVM ottiene il suo tempo dal (astratto) "orologio di sistema" operativo (che varia a seconda del sistema operativo in termini di come funziona). Vedi anche: drdobbs.com/embedded-systems/… e implementazioni "C" sui sistemi operativi chemie.fu-berlin.de/chemnet/use/info/libc/libc_17.html
Darrell Teague
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.