Kurze Antwort:
Date in = new Date();
LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault());
Date out = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
Erklärung: (basierend auf dieser Frage über LocalDate
)
Trotz seines Namens repräsentiert java.util.Date
einen Zeitpunkt auf der Zeitachse, nicht ein "Datum". Die tatsächlichen Daten, die im Objekt gespeichert sind, sind eine long
Zählung von Millisekunden seit 1970-01-01T00:00Z (Mitternacht am Anfang von 1970 GMT/UTC).
Die äquivalente Klasse zu java.util.Date
in JSR-310 ist Instant
, daher gibt es praktische Methoden, um die Konvertierung hin und zurück zu ermöglichen:
Date input = new Date();
Instant instant = input.toInstant();
Date output = Date.from(instant);
Ein java.util.Date
Instanz hat kein Konzept der Zeitzone. Das mag seltsam erscheinen, wenn Sie toString()
auf einem java.util.Date
aufrufen, weil das toString
relativ zu einer Zeitzone ist. Jedoch verwendet diese Methode tatsächlich die Standard-Zeitzone von Java, um den String bereitzustellen. Die Zeitzone ist kein Teil des tatsächlichen Zustands von java.util.Date
.
Ein Instant
enthält auch keine Informationen über die Zeitzone. Daher ist es notwendig, beim Konvertieren von einem Instant
zu einem lokalen Datum und Zeit eine Zeitzone anzugeben. Dies kann die Standardzone sein - ZoneId.systemDefault()
- oder es kann eine Zeitzone sein, die Ihre Anwendung kontrolliert, wie zum Beispiel eine Zeitzone aus den Benutzereinstellungen. LocalDateTime
hat eine praktische Fabrikmethode, die sowohl den Zeitpunkt als auch die Zeitzone akzeptiert:
Date in = new Date();
LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault());
Umgekehrt wird die Zeitzone in LocalDateTime
durch Aufrufen der Methode atZone(ZoneId)
festgelegt. Der ZonedDateTime
kann dann direkt in einen Instant
umgewandelt werden:
LocalDateTime ldt = ...
ZonedDateTime zdt = ldt.atZone(ZoneId.systemDefault());
Date output = Date.from(zdt.toInstant());
Bemerken Sie, dass die Konvertierung von LocalDateTime
zu ZonedDateTime
das Potenzial hat, unerwartetes Verhalten einzuführen. Dies liegt daran, dass nicht jede lokale Datum und Zeit aufgrund der Sommerzeit existiert. Im Herbst gibt es eine Überlappung in der lokalen Zeitachse, wo dieselbe lokale Datum und Zeit zweimal vorkommt. Im Frühjahr gibt es eine Lücke, wo eine Stunde verschwindet. Sehen Sie sich die Javadoc von atZone(ZoneId)
für die Definition dessen an, was die Konvertierung tun wird.
Zusammenfassend, wenn Sie eine java.util.Date
zu einem LocalDateTime
und zurück zu einem java.util.Date
umreisen, könnten Sie aufgrund der Sommerzeit einen anderen Zeitpunkt erhalten.
Zusätzliche Informationen: Es gibt einen weiteren Unterschied, der sehr alte Daten betreffen wird. java.util.Date
verwendet einen Kalender, der sich am 15. Oktober 1582 ändert, wobei Daten vor diesem Datum den julianischen Kalender anstelle des gregorianischen verwenden. Im Gegensatz dazu verwendet java.time.*
das ISO-Kalendersystem (äquivalent zum gregorianischen) für alle Zeiten. In den meisten Anwendungsfällen ist das ISO-Kalendersystem das, was Sie wollen, aber Sie können merkwürdige Effekte sehen, wenn Sie Daten vor dem Jahr 1582 vergleichen.