Java 8 verfügt über eine völlig neue API für Datum und Uhrzeit. Eine der nützlichsten Klassen in dieser API ist das LocalDateTime
Halten eines zeitzonenunabhängigen Datums-Zeit-Werts.
Es gibt wahrscheinlich Millionen von Codezeilen, die die Legacy-Klasse java.util.Date
für diesen Zweck verwenden. Wenn Sie also alten und neuen Code miteinander verbinden, müssen Sie zwischen beiden konvertieren. Wie kann dies getan werden, da es anscheinend keine direkten Methoden gibt, um dies zu erreichen?
Antworten:
Kurze Antwort:
Erklärung: (basierend auf dieser Frage über
LocalDate
)Stellt trotz seines Namens
java.util.Date
einen Moment auf der Zeitachse dar, kein "Datum". Die tatsächlich im Objekt gespeicherten Daten sindlong
Millisekunden seit 1970-01-01T00: 00Z (Mitternacht zu Beginn von 1970 GMT / UTC).Die äquivalente Klasse zu
java.util.Date
in JSR-310 istInstant
, daher gibt es bequeme Methoden, um die Konvertierung hin und her bereitzustellen:Eine
java.util.Date
Instanz hat kein Konzept der Zeitzone. Dies mag seltsam erscheinen , wenn Sie rufentoString()
auf einjava.util.Date
, weil dietoString
relativ zu einer Zeitzone ist. Diese Methode verwendet jedoch tatsächlich die Standardzeitzone von Java im laufenden Betrieb, um die Zeichenfolge bereitzustellen. Die Zeitzone ist nicht Teil des aktuellen Zustands vonjava.util.Date
.Ein
Instant
enthält auch keine Informationen über die Zeitzone. Um von einerInstant
in eine lokale Datums- / Uhrzeitangabe zu konvertieren, muss daher eine Zeitzone angegeben werden. Dies kann die Standardzone sein -ZoneId.systemDefault()
- oder eine Zeitzone, die Ihre Anwendung steuert, z. B. eine Zeitzone aus den Benutzereinstellungen.LocalDateTime
verfügt über eine praktische Factory-Methode, die sowohl die Sofort- als auch die Zeitzone berücksichtigt:Umgekehrt wird die
LocalDateTime
Zeitzone durch Aufrufen deratZone(ZoneId)
Methode angegeben. DasZonedDateTime
kann dann direkt in ein konvertiert werdenInstant
:Beachten Sie, dass die Konvertierung von
LocalDateTime
nachZonedDateTime
zu unerwartetem Verhalten führen kann. Dies liegt daran, dass aufgrund der Sommerzeit nicht jede lokale Datums- und Uhrzeitangabe vorhanden ist. Im Herbst / Herbst gibt es eine Überlappung in der lokalen Zeitleiste, in der dieselbe lokale Datums- und Uhrzeit zweimal vorkommt. Im Frühjahr gibt es eine Lücke, in der eine Stunde verschwindet. Weitere InformationenatZone(ZoneId)
zur Definition der Konvertierung finden Sie im Javadoc von .Zusammenfassung: Wenn Sie eine Hin- und Rückfahrt
java.util.Date
zu aLocalDateTime
und zurück zu a machenjava.util.Date
, kann es aufgrund der Sommerzeit zu einem anderen Zeitpunkt kommen.Zusätzliche Informationen: Es gibt einen weiteren Unterschied, der sich auf sehr alte Daten auswirkt.
java.util.Date
verwendet einen Kalender, der sich am 15. Oktober 1582 ändert, wobei Daten davor den julianischen Kalender anstelle des gregorianischen Kalenders verwenden. Im Gegensatz dazujava.time.*
wird das ISO-Kalendersystem (entspricht dem Gregorianischen) für alle Zeiten verwendet. In den meisten Anwendungsfällen ist das ISO-Kalendersystem genau das, was Sie möchten. Beim Vergleich der Daten vor dem Jahr 1582 können jedoch merkwürdige Auswirkungen auftreten.quelle
java.util.Date
enthält keine Zeitzone, aber drucken Sie es währendtoString()
. Die offizielle Dokumentation der Veranstaltung sagt dies beim Posten nicht klar aus.LocalDateTime.ofInstant(date.toInstant()...
verhält sich nicht so, wie man es naiv erwarten würde. Zum Beispielnew Date(1111-1900,11-1,11,0,0,0);
wird1111-11-17 23:53:28
dieser Ansatz verwendet. Sehen Sie sich die Implementierung an,java.sql.Timestamp#toLocalDateTime()
wenn Sie das Ergebnis1111-11-11 00:00:00
im vorherigen Beispiel benötigen .java.sql.Date#toInstant
wirftUnsupportedOperationException
. Also nichttoInstant
in einem RowMapper verwendenjava.sql.ResultSet#getDate
.Hier ist, was ich mir ausgedacht habe (und wie bei allen Datums- und Uhrzeit-Rätseln wird es wahrscheinlich aufgrund einer seltsamen Zeitzonen-Leapyear-Tageslicht-Anpassung widerlegt: D)
Rundauslösung:
Date
<<- >>LocalDateTime
Gegeben:
Date date = [some date]
(1)
LocalDateTime
<<Instant
<<Date
(2)
Date
<<Instant
<<LocalDateTime
Beispiel:
Gegeben:
(1)
LocalDateTime
<<Instant
<<Date
:Erstellen
Instant
ausDate
:Erstellen
Date
ausInstant
(nicht erforderlich, aber zur Veranschaulichung):Erstellen
LocalDateTime
ausInstant
(2)
Date
<<Instant
<<LocalDateTime
Erstellen
Instant
ausLocalDateTime
:Erstellen
Date
ausInstant
:Die Ausgabe ist:
quelle
Instant.ofEpochMilli(date.getTime())
dodate.toInstant()
toInstant()
sieht gut aus, außer es schlägt fehljava.sql.Date
, arggggh! So ist es endlich einfacher zu bedienenInstant.ofEpochMilli(date.getTime())
.Viel bequemer, wenn Sie sicher sind, dass Sie eine Standardzeitzone benötigen:
quelle
Folgendes scheint zu funktionieren, wenn von der neuen API LocalDateTime in java.util.date konvertiert wird:
Die umgekehrte Umwandlung kann (hoffentlich) auf ähnliche Weise erreicht werden ...
ich hoffe es hilft...
quelle
Alles ist hier: http://blog.progs.be/542/date-to-java-time
Die Antwort mit "Round-Tripping" ist nicht genau: wenn Sie dies tun
Wenn Ihre Systemzeitzone nicht UTC / GMT ist, ändern Sie die Zeit!
quelle
Der schnellste Weg für
LocalDateTime
->Date
ist:Date.from(ldt.toInstant(ZoneOffset.UTC))
quelle
Ich bin mir nicht sicher, ob dies der einfachste oder beste Weg ist oder ob es Fallstricke gibt, aber es funktioniert:
quelle
LocalDateTime
bisDate
. Bei SommerzeitübergängenLocalDateTime
kann a nicht vorhanden sein oder zweimal auftreten. Sie müssen herausfinden, was in jedem Fall passieren soll.GregorianCalendar
gehört alte umständliche API, die neuejava.time
API ersetzen sollWenn Sie auf Android sind und threetenbp verwenden , können Sie
DateTimeUtils
stattdessen verwenden.Ex:
Sie können nicht verwenden,
Date.from
da es nur auf API 26+ unterstützt wirdquelle