Was ist der beste Weg, um ein java.util.Date
Objekt in das neue JDK 8 / JSR-310 zu konvertieren java.time.LocalDate
?
Date input = new Date();
LocalDate date = ???
Kurze Antwort
Date input = new Date();
LocalDate date = input.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
Erläuterung
Stellt trotz seines Namens java.util.Date
einen Moment auf der Zeitachse dar, kein "Datum". Die tatsächlich im Objekt gespeicherten Daten sind long
Millisekunden seit 1970-01-01T00: 00Z (Mitternacht zu Beginn von 1970 GMT / UTC).
Die äquivalente Klasse zu java.util.Date
in JSR-310 ist Instant
, daher gibt es eine bequeme Methode toInstant()
, um die Konvertierung bereitzustellen:
Date input = new Date();
Instant instant = input.toInstant();
Eine java.util.Date
Instanz hat kein Konzept der Zeitzone. Dies mag seltsam erscheinen , wenn Sie rufen toString()
auf ein java.util.Date
, weil die toString
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 von java.util.Date
.
Ein Instant
enthält auch keine Informationen über die Zeitzone. Um von einem Instant
in ein lokales Datum 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. Verwenden Sie die atZone()
Methode, um die Zeitzone anzuwenden:
Date input = new Date();
Instant instant = input.toInstant();
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
A ZonedDateTime
enthält einen Status, der aus dem lokalen Datum und der Uhrzeit, der Zeitzone und dem Versatz von GMT / UTC besteht. Als solches kann das Datum - LocalDate
- leicht extrahiert werden mit toLocalDate()
:
Date input = new Date();
Instant instant = input.toInstant();
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
LocalDate date = zdt.toLocalDate();
Java 9 Antwort
In Java SE 9 wurde eine neue Methode hinzugefügt, die diese Aufgabe leicht vereinfacht:
Date input = new Date();
LocalDate date = LocalDate.ofInstant(input.toInstant(), ZoneId.systemDefault());
Diese neue Alternative ist direkter, verursacht weniger Müll und sollte daher eine bessere Leistung erbringen.
LocalDate.from(Instant.ofEpochMilli(date.getTime()))
ich denke, es ist gleichbedeutend mit deinem, aber direkter.Date
hat kein Konzept der Zeitzone und enthältInstant
auch keine Informationen zur Zeitzone. DieLocalDate
API sagt "Ein Datum ohne Zeitzone". Warum dann vonDate
zuInstant
zuLocalDate
Bedarf konvertierenatZone(ZoneId.systemDefault())
?LocalDate
und "LocalDateTime
keine Zeit oder Zeitzone speichern oder darstellen" (ref: javadocs). Während sie es nicht speichern, stellen die Klassen einLocal
Datum und / oder eine Uhrzeit dar, daher impliziert die Konvertierung in lokales Datum / Uhrzeit eine Zeitzone.Besser ist:
Vorteile dieser Version:
funktioniert unabhängig
java.util.Date
davon,java.sql.Date
ob die Eingabe eine Instanz oder eine Unterklasse von ist (im Gegensatz zu @ JodaStephen). Dies ist bei JDBC-Daten üblich.java.sql.Date.toInstant()
löst immer eine Ausnahme aus.Dies gilt auch für JDK8 und JDK7 mit JSR-310-Backport
Ich persönlich verwende eine Utility-Klasse (diese ist jedoch nicht Backport-kompatibel):
Die
asLocalDate()
hier verwendete Methode ist nullsicher und wird verwendettoLocalDate()
, wenn die Eingabe erfolgtjava.sql.Date
(sie kann vom JDBC-Treiber überschrieben werden, um Zeitzonenprobleme oder unnötige Berechnungen zu vermeiden). Andernfalls wird die oben genannte Methode verwendet.quelle
DateConvertUtils
.Date.toInstant()
.quelle
SimpleDateFormat
Instanz auf den aktuellen Thread beschränkt. Es wird verwendet in einem Thread-sicher. NunSimpleDateFormat
ist angeblich zu sein ‚teuer instantiate‘ (wegen aller internen Datenstrukturen es braucht) , aber man kann nicht teilen ein als ‚Singleton‘ (ohne Zugang zu ihm zu synchronisieren), weil es in der Tat nicht Gewinde- ist sicher. (EineThreadLocal
Lösung kann funktionieren, wenn der Code, der den darin enthaltenen Code verschmutzt,Thread
für den Lebenszyklus des Threads verantwortlich ist ... aber das kommt selten vor). Peinlich. VermeidenSimpleDateFormat
ist der Grund für die Verwendungjavax.time
.SimpleDateFormat
(die weggeworfen wird), die Zwischenzeichenfolge (die weggeworfen wird) und die Kosten für das Parsen. Es ist eine Lösung, aber nicht zu empfehlen.Wenn Sie Java 8 verwenden, ist die Antwort von @ JodaStephen offensichtlich die beste. Wenn Sie jedoch mit dem JSR-310-Backport arbeiten , müssen Sie leider Folgendes tun:
quelle
quelle
Sie können in einer Zeile konvertieren:
quelle
Erstens ist es einfach, ein Datum in einen Instant umzuwandeln
Anschließend können Sie den Instant mit der Methode ofInstant () in eine beliebige Datums-API in JDK 8 konvertieren:
quelle
import java.sql.Date
in Ihrer Datei haben: dietoInstant()
Methode,java.sql.Date
immer zu werfen.Die
Date
Instanz enthält neben dem Datum auch die Uhrzeit, währendLocalDate
dies nicht der Fall ist. Sie können es also zuerstLocalDateTime
mit seiner Methode konvertieren undofInstant()
dann, wenn Sie es ohne Zeit möchten , die Instanz in konvertierenLocalDate
.quelle
Dieses Format ist von
Date#tostring
quelle
Ich hatte Probleme mit der Implementierung von @ JodaStephen in JBoss EAP 6. Daher habe ich die Konvertierung nach dem Java-Tutorial von Oracle unter http://docs.oracle.com/javase/tutorial/datetime/iso/legacy.html neu geschrieben .
quelle
Was ist los mit dieser 1 einfachen Zeile?
quelle
Ich habe diese Frage mit der folgenden Lösung gelöst
In diesem Fall drucken localDate Ihr Datum in diesem Format "JJJJ-MM-TT".
quelle
java.time
Klassen in JDK8, nicht mit Joda Time.