java.time
Med udgivelsen af Java SE 8 i marts 2014, den forældede og fejltilbøjelige ældre Date-Time API (java.util
Dato-tidstyper og deres formateringstype, SimpleDateFormat
osv.) blev erstattet af java.time
, den moderne Date-Time API. Den følgende tabel
viser kortlægningen af ANSI SQL-typer med java.time
typer:
ANSI SQL | Java SE 8 |
---|---|
DATO | LocalDate |
TID | Lokaltid |
TIMESTAMP | LocalDateTime |
TID MED TIDSZONE | OffsetTime |
TIMESTAMP MED TIMEZONE | OffsetDateTime |
Bemærk, at ZonedDateTime
og Instant
understøttes ikke af nogen JDBC-driver, hvorimod nogle drivere, f.eks. PostgreSQL understøtter heller ikke OffsetTime
/ TIME [ WITHOUT TIMEZONE ]
. Bemærk også, at alle OffsetDateTime
forekomster skal være i UTC (have offset 0). Dette er fordi backend gemmer dem som UTC.
Hvordan bruges det i JDBC?
Nedenstående er en eksempelkode til at indsætte den aktuelle OffsetDateTime
i UTC, ind i columnfoo
(som er af TIMESTAMP WITH TIMEZONE
type):
OffsetDateTime odt = Instant.now().atOffset(ZoneOffset.UTC);
PreparedStatement st = conn.prepareStatement("INSERT INTO mytable (columnfoo) VALUES (?)");
st.setObject(1, odt);
st.executeUpdate();
st.close();
En Instant
repræsenterer et øjeblikkeligt punkt på tidslinjen og er uafhængig af en tidszone, dvs. den har en tidszoneforskydning på +00:00
timer.
Nedenstående er en eksempelkode til at hente en OffsetDateTime
fra 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();
Bare hvis du har brug for at konvertere en OffsetDateTime
ind i en anden med en anden offset:
Der er flere måder at gøre det på, men jeg bruger mest OffsetDateTime#withOffsetSameInstant
, for at konvertere en OffsetDateTime
ind i en anden med en anden tidszoneforskydning, f.eks.
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);
}
}
Output:
2021-05-29T13:36:15.258076Z
2021-05-29T15:36:15.258076+02:00
2021-05-29T14:36:15.258076+01:00
Nogle punkter relateret til koden ovenfor:
Z
i outputtet er tidszonebetegnelsen for nul-tidszone offset. Det står for Zulu og angiverEtc/UTC
tidszone (som har tidszoneforskydningen på+00:00
timer).- Koden konverterer
odt
i to forekomster afOffsetDateTime
- hver på en anden måde. Den første instans er med en fast tidszoneforskydning på+02:00
timer, hvorimod den anden er med tidszoneforskydningen af JVM. Bemærk, at tidszoneforskydningen for et sted, der observerer DST ændringer i forhold til sommer/vintertid. Derfor, hvis et sted observerer sommertid, i stedet for at bruge en fast tidszone offset, f.eks.+02:00
timer; vi burde hente det fra API'et. - Min JVMs tidszone er
Europe/London
og i øjeblikket er dens offset+01:00
timer.
Få mere at vide om moderne date-time API a> fra Trail:Date Time .