Wie konvertiere ich java.sql.timestamp in LocalDate (java8) java.time?

Antworten:

195

Du kannst tun:

timeStamp.toLocalDateTime().toLocalDate();

Beachten Sie, dass timestamp.toLocalDateTime() die Clock.systemDefaultZone()Zeitzone für die Konvertierung verwendet wird. Dies kann oder kann nicht sein, was Sie wollen.

Assylien
quelle
1
Es wurde in Java 8 hinzugefügt.
Assylias
54
Nur eine Anmerkung, die timestamp.toLocalDateTime()Methode verwendet die Zeitzone systemDefault, um die Konvertierung durchzuführen. Dies kann oder kann nicht sein, was Sie wollen.
jacobhyphenated
1
@jacobhyphenated Bitte poste die Antwort mit einer expliziten Zeitzone. Vielen Dank!
user482745
@ jacobhyphenateds Kommentar ist hier extrem wichtig, daher die Anzahl der Upvotes dafür. Siehe meine Antwort für Details stackoverflow.com/a/57101544/2032701
Ruslan
@jacobhyphenated, verwendet LocalDateTimeimmer die Standard-Zeitzone des Systems. Das ist es, was "Lokal" in seinem Namen bedeutet.
M. Prokhorov
20

Die akzeptierte Antwort ist nicht ideal, deshalb habe ich beschlossen, meine 2 Cent hinzuzufügen

timeStamp.toLocalDateTime().toLocalDate();

ist im Allgemeinen eine schlechte Lösung . Ich bin mir nicht einmal sicher, warum sie diese Methode zum JDK hinzugefügt haben, da sie die Dinge durch eine implizite Konvertierung unter Verwendung der Systemzeitzone wirklich verwirrend macht. Wenn der Programmierer nur Java8-Datumsklassen verwendet, muss er normalerweise eine Zeitzone angeben, was eine gute Sache ist.

Die gute Lösung ist

timestamp.toInstant().atZone(zoneId).toLocalDate()

Dabei ist zoneId die Zeitzone, die Sie verwenden möchten. Dies ist normalerweise entweder ZoneId.systemDefault (), wenn Sie Ihre Systemzeitzone verwenden möchten, oder eine fest codierte Zeitzone wie ZoneOffset.UTC

Der allgemeine Ansatz sollte sein

  1. Befreien Sie sich von den neuen java8-Datumsklassen mit einer Klasse, die in direktem Zusammenhang steht, z. B. in unserem Fall java.time.Instant in direktem Zusammenhang mit java.sql.Timestamp , dh es sind keine Zeitzonenkonvertierungen zwischen ihnen erforderlich.
  2. Verwenden Sie die gut gestalteten Methoden in dieser Java8-Klasse, um das Richtige zu tun. In unserem Fall hat atZone (zoneId) deutlich gemacht, dass wir eine Konvertierung durchführen und eine bestimmte Zeitzone dafür verwenden.
Ruslan
quelle
1
Ich bin nicht einverstanden. Der Zeitstempel (und auch das Datum) enthalten keine Zoneninformationen. LocalDate hat keine Zoneninformationen, daher sind beide gleichwertig. Die Konvertierung zwischen ihnen kann unabhängig von einer bestimmten Zone erfolgen. Wenn Sie vor dem Konvertieren in LocalDate in eine ZonedDateTime konvertieren, wird eine Zeitzone hinzugefügt und dann wieder entfernt.
AutomatedMike
5
@AutomatedMike Timestamp (und auch Date) repräsentieren einen Zeitpunkt in UTC. LocalDate repräsentiert keinen Zeitpunkt, sondern eine Zeit, wie sie auf einer Wanduhr zu sehen ist. Bitte lesen Sie ihre Javadocs. "Die Konvertierung zwischen ihnen kann unabhängig von einer bestimmten Zone erfolgen" - nicht wahr , der neue Zeitstempel (0L) .toLocalDateTime () gibt "1970-01-01T03: 00" für meine Moskauer Zeitzone zurück. Das Ergebnis kann für Ihre Zeitzone unterschiedlich sein.
Ruslan
1
@AutomatedMike Selbst wenn Sie die Zeit mit toLocalDate () entfernen, können Sie leicht beweisen, dass der Tag falsch sein kann, wenn der Zeitstempel eine Zeit um Mitternacht hat, z. B. der neue Zeitstempel (1000 * 60 * 60 * 23) .toLocalDateTime (). ToLocalDate () gibt "1970-01-02" für meine Moskauer Zeitzone zurück, wenn es "1970-01-01" in UTC ist.
Ruslan
1
@AutomatedMike "fügt eine Zeitzone hinzu und nimmt sie dann wieder ab" - der Punkt ist nicht das Hinzufügen und Entfernen einer Zeitzone, sondern das Konvertieren zwischen verschiedenen Begriffen mithilfe einer expliziten Zeitzone. Dies steht im Gegensatz zu den Beispielen meiner beiden vorherigen Kommentare, in denen eine Zeitzone implizit angewendet wird .
Ruslan
7

Ich werde die Antwort von @assylias leicht erweitern, um die Zeitzone zu berücksichtigen. Es gibt mindestens zwei Möglichkeiten, LocalDateTime für eine bestimmte Zeitzone abzurufen.

Sie können die setDefault-Zeitzone für die gesamte Anwendung verwenden. Es sollte vor jedem Zeitstempel aufgerufen werden -> java.time-Konvertierung:

public static void main(String... args) {
    TimeZone utcTimeZone = TimeZone.getTimeZone("UTC");
    TimeZone.setDefault(utcTimeZone);
    ...
    timestamp.toLocalDateTime().toLocalDate();
}

Oder Sie können die Kette toInstant.atZone verwenden:

timestamp.toInstant()
        .atZone(ZoneId.of("UTC"))
        .toLocalDate();
Pavel
quelle