Gibt System.currentTimeMillis () die UTC-Zeit zurück?

93

Ich möchte die aktuelle UTC-Zeit in Millis erhalten. Ich habe bei Google gesucht und einige Antworten erhalten, dass System.currentTimeMillis () die UTC-Zeit zurückgibt. aber das tut es nicht. Wenn ich folgendes mache:

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

Alle drei Zeiten sind fast gleich (Unterschied in Millisekunden aufgrund von Anrufen).

t1 = 1372060916
t2 = 1372060917
t3 = 1372060918

und diese Zeit ist nicht die UTC-Zeit, sondern meine Zeitzonenzeit. Wie kann ich die aktuelle UTC-Zeit in Android erhalten?

g.revolution
quelle
4
Gibt die aktuelle Systemzeit in Millisekunden seit dem 1. Januar 1970 00:00:00 UTC
Blackbelt
3
long t3 = Calendar.getInstance (TimeZone.getTimeZone ("UTC")). getTimeInMillis ();
Blackbelt
3
Der obige Link lautet: "In der Beschreibung der Klasse Datum finden Sie Erläuterungen zu geringfügigen Abweichungen, die zwischen" Computerzeit "und koordinierter Weltzeit (UTC) auftreten können." und in der Dokumentation zu java.util.Date finden Sie: "Obwohl die Date-Klasse die koordinierte Weltzeit (UTC) widerspiegeln soll, funktioniert dies möglicherweise nicht genau, abhängig von der Host-Umgebung der Java Virtual Machine." -> Möglicherweise Möglicherweise gibt Ihre Maschine eine Nicht-UTC-Zeit zurück
Marco Forberg
4
@ g.revolution: Es ist "die Anzahl der Millisekunden seit dem 1. Januar 1970, 00:00:00 UTC" - wie würden Sie erwarten, dass sich dies für eine Zeitzone anpasst? Ihre lokale Zeitzone hat keinen Einfluss darauf, wie viele Millisekunden seit dieser Epoche aufgetreten sind.
Jon Skeet

Antworten:

132

Alle drei von Ihnen angezeigten Linien geben die Anzahl der Millisekunden seit der Unix-Epoche an, die ein fester Zeitpunkt ist und nicht von Ihrer lokalen Zeitzone beeinflusst wird.

Sie sagen "diesmal ist nicht die UTC-Zeit" - ich vermute, Sie haben das tatsächlich falsch diagnostiziert. Ich würde vorschlagen, dafür epochconverter.com zu verwenden. Zum Beispiel in Ihrem Beispiel:

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

Wir wissen nicht, wann Sie diesen Wert generiert haben, aber es sei denn, es war tatsächlich so um 8:01 Uhr UTC, es ist ein Problem mit Ihrer Systemuhr.

Weder System.currentTimeMillisnoch der Wert innerhalb eines Dateselbst werden von der Zeitzone beeinflusst. Allerdings sollten Sie beachten, dass Date.toString() sich die lokale Zeitzone verwenden, die verleitet viele Entwickler zu denken , dass ein von DateNatur aus mit einer Zeitzone zugeordnet ist - es ist nicht, es ist nur ein Augenblick in der Zeit, ohne eine zugehörige Zeitzone oder sogar Kalendersystem.

Jon Skeet
quelle
6
Das heißt also im Grunde, dass diese Funktion den gleichen Wert zurückgibt, wenn sie zur gleichen Zeit aus verschiedenen Zeitzonen aufgerufen wird, unabhängig von der Uhr des Hosts, richtig?
Phillip
14
Mann, das lässt mich wünschen, die Welt würde (könnte) eine einzige Zeitzone annehmen. Wen interessiert es, ob die Zahl auf der Uhr 00:00 oder 08:00 ist, wenn das große helle Ding am Himmel erscheint? Die unzähligen Stunden ansonsten produktiver Zeit, die für dieses historische Relikt verschwendet werden, lassen mein Blut kochen ...
corsiKa
Beachten Sie im Zusammenhang damit, dass der zugrunde liegende Aufruf der Betriebssystemuhrfunktion eine dokumentierte Drift von mehreren Millisekunden aufweist. Java verfügt über einen Hochleistungstimer, wenn eine hochpräzise Dauer einer Operation ermittelt werden soll (Zeitpunkt, zu dem eine Aufgabe gestartet und beendet wird, wobei das Delta die verstrichene Zeit ist). Siehe: docs.oracle.com/javase/7/docs/api/java/lang/…
Darrell Teague
@ JonSkeet Wenn toString () intern die Zeitzone verwendet, wie könnte ich ohne Zeitzone einen String daraus erstellen? Eigentlich generiere ich eine Datei auf dem REST-Server, deren Dateiname genau den Mitternachtszeitwert ex "1551139200.json" (26. Februar 2019, 00:00:00 Uhr) hat und auf den über die Android-App zugegriffen werden muss, sobald das System.currentTimeMillis () des Geräts vorhanden ist. gibt die genaue Zeit zurück.
Kiranking
@kiranking: Verwenden Sie diese Option Date.getTime(), um die Millisekunden seit der Unix-Epoche zu ermitteln, durch 1000 zu teilen (da dieser Dateiname seit der Unix-Epoche in Sekunden angegeben ist) und diese Ganzzahl einfach als Zeichenfolge zu formatieren.
Jon Skeet
3

Ich kann bestätigen , dass alle drei Anrufe können auf der lokalen Zeit abhängen, die Epoche unter Berücksichtigung, nicht dieDate.toString() oder ein ähnliches Verfahren. Ich habe gesehen, dass sie von der Ortszeit auf bestimmten Geräten mit Android 2.3 abhängen. Ich habe sie nicht mit anderen Geräten und Android-Versionen getestet. In diesem Fall wurde die Ortszeit manuell eingestellt.

Der einzige zuverlässige Weg, um eine unabhängige UTC-Zeit zu erhalten, besteht darin, eine Standortaktualisierung mithilfe von anzufordern GPS_PROVIDER. Der getTime()Wert eines Speicherorts, von dem abgerufen wurdeNETWORK_PROVIDER hängt auch von der Ortszeit ab. Eine andere Option ist das Pingen eines Servers, der beispielsweise einen UTC-Zeitstempel zurückgibt.

Also mache ich Folgendes:

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;
}
jlhonora
quelle
1
System.currentTimeMillis () gibt einen UTC-basierten Wert zurück. Die "Präzision" oder Genauigkeit der Uhr des Betriebssystems ist zwar betroffen, dies wirkt sich zwar auf das Ergebnis aus, hängt jedoch in keiner Weise mit dem Zeitzonenwert des Systems oder der Java-Umgebung zusammen.
Darrell Teague
@DarrellTeague Ich bestehe darauf, dass ich in einem bestimmten Huawei-Gerät unterschiedliche Werte gesehen habe. Also nein, es wird nicht immer die richtige UTC-Zeit zurückgegeben (Genauigkeitsunterschiede werden
verworfen
Die Frage des OP betraf die Verwendung einer Zeitzone in der Java-Klasse. Hier ging es nicht um Hardware oder die Genauigkeit des zurückgegebenen Zeitwerts. Einfach ausgedrückt, bezieht die JVM ihre Zeit aus der (abstrakten) "Betriebssystemuhr" (die je nach Betriebssystem in Bezug auf ihre Funktionsweise variiert). Siehe auch: drdobbs.com/embedded-systems/… und "C" -Implementierungen
Darrell Teague