java.time
Mit der Veröffentlichung von Java SE 8 im März 2014 wurde die veraltete und fehleranfällige veraltete Date-Time-API (java.util
Date-Time-Typen und ihr Formatierungstyp, SimpleDateFormat
usw.) wurde durch java.time
ersetzt , die moderne Date-Time-API. Die folgende Tabelle
zeigt die Abbildung von ANSI-SQL-Typen mit java.time
Typen:
ANSI-SQL | Java SE 8 |
---|---|
DATUM | Lokales Datum |
ZEIT | Ortszeit |
ZEITSTEMPEL | LocalDateTime |
ZEIT MIT ZEITZONE | OffsetZeit |
ZEITSTEMPEL MIT ZEITZONE | OffsetDateTime |
Beachten Sie, dass ZonedDateTime
und Instant
werden von keinem JDBC-Treiber unterstützt, während einige Treiber, z. PostgreSQL unterstützt auch nicht OffsetTime
/ TIME [ WITHOUT TIMEZONE ]
. Beachten Sie außerdem, dass alle OffsetDateTime
Instanzen müssen in UTC sein (Offset 0 haben). Dies liegt daran, dass das Backend sie als UTC speichert.
Wie wird es in JDBC verwendet?
Unten ist ein Beispielcode zum Einfügen der aktuellen OffsetDateTime
in UTC, in columnfoo
(das ist TIMESTAMP WITH TIMEZONE
Typ):
OffsetDateTime odt = Instant.now().atOffset(ZoneOffset.UTC);
PreparedStatement st = conn.prepareStatement("INSERT INTO mytable (columnfoo) VALUES (?)");
st.setObject(1, odt);
st.executeUpdate();
st.close();
Ein Instant
stellt einen augenblicklichen Punkt auf der Zeitachse dar und ist unabhängig von einer Zeitzone, d. h. es hat einen Zeitzonen-Offset von +00:00
Stunden.
Unten ist ein Beispielcode zum Abrufen einer OffsetDateTime
aus columnfoo
:
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM mytable WHERE <some condition>");
while (rs.next()) {
// Assuming the column index of columnfoo is 1
OffsetDateTime odt = rs.getObject(1, OffsetDateTime.class));
System.out.println(odt);
}
rs.close();
st.close();
Nur für den Fall, dass Sie eine OffsetDateTime
konvertieren müssen in eine andere mit einem anderen Offset:
Dafür gibt es mehrere Möglichkeiten, aber meistens verwende ich OffsetDateTime#withOffsetSameInstant
, um eine OffsetDateTime
zu konvertieren in eine andere mit einem anderen Zeitzonen-Offset, z. B.
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
// A sample OffsetDateTime in UTC.
OffsetDateTime odt = Instant.now().atOffset(ZoneOffset.UTC);
System.out.println(odt);
OffsetDateTime offsetTimeAtOffset0100 = odt.withOffsetSameInstant(ZoneOffset.of("+02:00"));
System.out.println(offsetTimeAtOffset0100);
// Time at JVM's default timezone offset
ZoneOffset jvmTzOffset = ZonedDateTime.now(ZoneId.systemDefault()).getOffset();
OffsetDateTime offsetTimeAtJvmTzOffset = odt.withOffsetSameInstant(jvmTzOffset);
System.out.println(offsetTimeAtJvmTzOffset);
}
}
Ausgabe:
2021-05-29T13:36:15.258076Z
2021-05-29T15:36:15.258076+02:00
2021-05-29T14:36:15.258076+01:00
Einige Punkte im Zusammenhang mit dem oben angegebenen Code:
- Das
Z
in der Ausgabe ist der Zeitzonenbezeichner für Null-Zeitzonen-Offset. Es steht für Zulu und gibt denEtc/UTC
an timezone (mit dem Zeitzonen-Offset von+00:00
Stunden). - Der Code konvertiert
odt
in zwei Instanzen vonOffsetDateTime
– jeder anders. Die erste Instanz ist mit einem festen Zeitzonen-Offset von+02:00
Stunden, während die zweite mit dem Zeitzonen-Offset der JVM ist. Beachten Sie, dass der Zeitzonenoffset eines Ortes DST einhält Änderungen je nach Sommer-/Winterzeit. Wenn also an einem Ort die Sommerzeit eingehalten wird, anstatt einen festen Zeitzonen-Offset zu verwenden, z.+02:00
Std; wir sollten es von der API bekommen. - Die Zeitzone meiner JVM ist
Europe/London
und derzeit ist sein Offset+01:00
Stunden.
Erfahren Sie mehr über die modernen Date-Time-API aus Trail:Date Time .