Wie bekomme ich UTC + 0 Datum in Java 8?

108

Ich habe Probleme mit der Date-Klasse in Java. Die Datumsklasse gibt das Datum des lokalen Computers zurück, aber ich benötige UTC-0.

Ich habe gegoogelt und eine großartige Lösung für JavaScript gefunden, aber für Java nichts Nützliches.

Wie bekomme ich UTC + 0 Datum in Java 8?

Kennzeichen
quelle
12
java.util.Dateist niemals ein lokales Maschinendatum. Es wird seit 1970-01-01 relativ zu UTC + 00: 00 immer als verstrichene Millisekunden definiert. Vielleicht toString()verwirrt Sie das Verhalten seiner Methode , die tatsächlich eine Darstellung in der lokalen Zeitzone verwendet.
Meno Hochschild
Eine wahrscheinliche Antwort kann in der Frage gefunden werden: stackoverflow.com/questions/45350095/…
Priya Jain

Antworten:

146

Mit Java 8 können Sie schreiben:

OffsetDateTime utc = OffsetDateTime.now(ZoneOffset.UTC);

Um Ihren Kommentar zu beantworten, können Sie ihn dann in ein Datum (es sei denn, Sie sind von Legacy-Code abhängig, ich sehe keinen Grund dafür) oder in Millis seit den Epochen konvertieren:

Date date = Date.from(utc.toInstant());
long epochMillis = utc.toEpochSecond() * 1000;
Assylien
quelle
1
Vielen Dank. ist es möglich, ZonedDateTime in Date oder in long (ms) zu konvertieren?
Mark
7
Obwohl der Code dieser Antwort technisch funktioniert, wäre es nicht angemessener, ihn zu verwenden, OffsetDateTimeals ZonedDateTimevorausgesetzt, dass wir nur mit einem Versatz von UTC anstatt mit einer Vollzeitzone arbeiten?
Basil Bourque
179

tl; dr

Instant.now()

java.time

Die problematischen alten Datums- und Uhrzeitklassen , die mit den frühesten Versionen von Java gebündelt wurden, wurden durch die in Java 8 und höher integrierten java.time- Klassen ersetzt. Siehe Oracle Tutorial . Ein Großteil der Funktionen wurde in ThreeTen-Backport auf Java 6 & 7 zurückportiert und in ThreeTenABP weiter an Android angepasst .

Instant

An Instantrepräsentiert einen Moment auf der Zeitachse in UTC mit einer Auflösung von bis zu Nanosekunden .

Instant instant = Instant.now();

Die toStringMethode generiert ein String-Objekt mit Text, der den Datums- / Uhrzeitwert darstellt, unter Verwendung eines der Standardformate ISO 8601 .

String output = instant.toString();  

2016-06-27T19: 15: 25.864Z

Die InstantKlasse ist eine grundlegende Bausteinklasse in java.time. Dies sollte Ihre erste Adresse beim Umgang mit Datum und Uhrzeit sein, da im Allgemeinen die beste Vorgehensweise darin besteht, Datums- und Uhrzeitwerte in UTC zu verfolgen, zu speichern und auszutauschen.

OffsetDateTime

Es Instantgibt jedoch Einschränkungen, z. B. keine Formatierungsoptionen zum Generieren von Zeichenfolgen in alternativen Formaten. Konvertieren Sie für mehr Flexibilität von Instantnach OffsetDateTime. Geben Sie einen Versatz von UTC an . In java.time bedeutet das ein ZoneOffsetObjekt. Hier wollen wir bei UTC (+00) bleiben, damit wir die bequeme Konstante verwenden können ZoneOffset.UTC.

OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC );

2016-06-27T19: 15: 25.864Z

Oder überspringen Sie die InstantKlasse.

OffsetDateTime.now( ZoneOffset.UTC )

Mit einem OffsetDateTimeObjekt in der Hand können Sie jetzt DateTimeFormatterString-Objekte mit Text in alternativen Formaten erstellen. Durchsuchen Sie den Stapelüberlauf nach vielen Anwendungsbeispielen DateTimeFormatter.

ZonedDateTime

Wenn Sie anzeigen möchten , Wand-Uhr Zeit für einige bestimmte Zeitzone, gilt eine ZoneIdeine zu bekommen ZonedDateTime.

In diesem Beispiel wenden wir die Zeitzone Montréal an. Im Sommer hat die Zone unter dem Unsinn der Sommerzeit (DST) einen Versatz von -04:00. So Kenntnis , wie die Zeit-of-Tag vier Stunden zuvor in der Ausgabe, 15statt 19Stunden. Instantund ZonedDateTimebeide repräsentieren den gleichen gleichzeitigen Moment, nur durch zwei verschiedene Linsen betrachtet.

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );

2016-06-27T15: 15: 25.864-04: 00 [Amerika / Montreal]

Konvertieren

Während Sie die alten Datums- / Uhrzeitklassen vermeiden sollten, können Sie bei Bedarf mit neuen Methoden konvertieren, die zu den alten Klassen hinzugefügt wurden. Hier verwenden wir java.util.Date.from( Instant )und java.util.Date::toInstant.

java.util.Date utilDate = java.util.Date.from( instant );

Und in die andere Richtung gehen.

Instant instant= utilDate.toInstant();

Suchen Sie in ähnlicher Weise nach neuen Methoden, die zu GregorianCalendar(Unterklasse von Calendar) hinzugefügt wurden , um von und nach zu konvertieren java.time.ZonedDateTime.

Tabelle der Arten von Datums- und Uhrzeitklassen in modernem Java.time versus Legacy.

Über java.time

Das java.time- Framework ist in Java 8 und höher integriert. Diese Klassen verdrängen die lästigen alten Legacy - Datum-Zeit - Klassen wie java.util.Date, Calendar, & SimpleDateFormat.

Weitere Informationen finden Sie im Oracle-Lernprogramm . Suchen Sie im Stapelüberlauf nach vielen Beispielen und Erklärungen. Die Spezifikation ist JSR 310 .

Das Joda-Time- Projekt, das sich jetzt im Wartungsmodus befindet , empfiehlt die Migration zu den Klassen java.time .

Sie können java.time- Objekte direkt mit Ihrer Datenbank austauschen . Verwenden Sie einen JDBC-Treiber, der mit JDBC 4.2 oder höher kompatibel ist . Keine Notwendigkeit für Zeichenfolgen, keine Notwendigkeit für java.sql.*Klassen. Hibernate 5 und JPA 2.2 unterstützen java.time .

Woher bekomme ich die java.time-Klassen?

Basil Bourque
quelle
3
Schätzen Sie,
Wenn es also keine Sommerzeit gäbe, ZonedDateTimewäre sie nicht erforderlich, da alle ZoneIdauf eine ZoneOffsetabgebildet würden, die wir nur verwenden könnten OffsetDateTime.
Wilmol
1
@wilmol Nein. Sommerzeit (DST) ist nur einer von vielen Gründen, warum Politiker die Zeitzonengrenzen und -versätze innerhalb dieser Zonen neu definieren. Kürzlich hat Nordkorea aus diplomatischen Gründen seine Uhr um eine halbe Stunde geändert, um sich mit Südkorea zu synchronisieren. Im Krieg können die Invasoren / Besatzer den Versatz an den des Heimatlandes anpassen. Derzeit gibt es eine neue Modeerscheinung, in der Regierungen beschließen, Änderungen der Sommerzeit zu stoppen, aber dauerhaft in der Sommerzeit bleiben, anstatt zu ihrer vorherigen Standardzeit zurückzukehren. Planen Sie immer den Versatz jeder Zonenänderung ein, da sonst Ihre App irgendwann kaputt geht.
Basil Bourque
1
Fantastische Antwort! Ich schätze die Zeit, die Sie dafür aufgewendet haben, sehr. :)
Drognisep
ZoneId.of ("Amerika / Montreal"); warum sollte jemand so etwas in jdk erfinden? Es ist hässlich, ekelhaft und sagt nicht, ob bis zur Laufzeit etwas nicht stimmt. Wer kann sich an all diesen harten Code erinnern? warum nicht in der ENUM-Klasse implementieren?
Workplaylifecycle
4

In Java8 würde ich die InstantKlasse verwenden, die sich bereits in UTC befindet und mit der man bequem arbeiten kann.

import java.time.Instant;

Instant ins = Instant.now();
long ts = ins.toEpochMilli();

Instant ins2 = Instant.ofEpochMilli(ts)

Alternativ können Sie Folgendes verwenden:

import java.time.*;

Instant ins = Instant.now(); 

OffsetDateTime odt = ins.atOffset(ZoneOffset.UTC);
ZonedDateTime zdt = ins.atZone(ZoneId.of("UTC"));

Zurück zu Instant

Instant ins4 = Instant.from(odt);
Abel Terefe
quelle
3
Nein, ein Instantist nicht zur Ortszeit. Ein Instantper Definition ist in UTC. Die in dieser Antwort gezeigten Machenschaften, die versuchen, in UTC zu gelangen, sind also nicht erforderlich. die Instantbereits ist in UTC. Weitere Informationen und viel einfacheren Code finden Sie in meiner Antwort .
Basil Bourque
Danke für den Kommentar.
Abel Terefe
0

1-Zeilen-Lösung in Java 8:

public Date getCurrentUtcTime() {
    return Date.from(Instant.now());
}
Abhijeet Ashok Muneshwar
quelle