java.time
Met de release van Java SE 8 in maart 2014 is de verouderde en foutgevoelige legacy Date-Time API (java.util
Datum-tijdtypes en hun opmaaktype, SimpleDateFormat
etc.) werd vervangen door java.time
, de moderne Date-Time API. De volgende tabel
toont de toewijzing van ANSI SQL-typen met java.time
soorten:
ANSI SQL | Java SE 8 |
---|---|
DATUM | Lokale datum |
TIJD | LocalTime |
TIMESTAMP | LocalDateTime |
TIJD MET TIJDZONE | OffsetTime |
TIMESTAMP MET TIJDZONE | OffsetDateTime |
Merk op dat ZonedDateTime
en Instant
worden door geen enkel JDBC-stuurprogramma ondersteund, terwijl sommige stuurprogramma's, b.v. PostgreSQL biedt ook geen ondersteuning voor OffsetTime
/ TIME [ WITHOUT TIMEZONE ]
. Merk ook op dat alle OffsetDateTime
instanties moeten in UTC zijn (offset 0 hebben). Dit komt omdat de backend ze opslaat als UTC.
Hoe te gebruiken in JDBC?
Hieronder vindt u een voorbeeldcode om de huidige OffsetDateTime
in te voegen in UTC, in columnfoo
(die van TIMESTAMP WITH TIMEZONE
. is 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();
Een Instant
vertegenwoordigt een ogenblikkelijk punt op de tijdlijn en is onafhankelijk van een tijdzone, d.w.z. het heeft een tijdzoneverschuiving van +00:00
uur.
Hieronder vindt u een voorbeeldcode voor het ophalen van een OffsetDateTime
van 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();
Voor het geval je een OffsetDateTime
moet converteren in een andere met een andere offset:
Er zijn verschillende manieren om dit te doen, maar ik gebruik meestal OffsetDateTime#withOffsetSameInstant
, om een OffsetDateTime
. te converteren naar een andere met een andere tijdzone-offset, bijvoorbeeld
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);
}
}
Uitvoer:
2021-05-29T13:36:15.258076Z
2021-05-29T15:36:15.258076+02:00
2021-05-29T14:36:15.258076+01:00
Enkele punten met betrekking tot de hierboven gegeven code:
- De
Z
in de uitvoer is de tijdzone-aanduiding voor nul-tijdzone offset. Het staat voor Zulu en specificeert deEtc/UTC
tijdzone (die de tijdzone-offset heeft van+00:00
uur). - De code converteert
odt
in twee gevallen vanOffsetDateTime
- elk op een andere manier. De eerste instantie is met een vaste tijdzoneverschuiving van+02:00
uur terwijl de tweede is met de tijdzone-offset van de JVM. Merk op dat de tijdzoneverschuiving van een plaats waar DST verandert volgens de zomer-/wintertijd. Daarom, als een plaats DST in acht neemt, in plaats van een vaste tijdzone-offset te gebruiken, b.v.+02:00
uur; we zouden het van de API moeten halen. - De tijdzone van mijn JVM is
Europe/London
en momenteel is de offset+01:00
uur.
Meer informatie over de moderne date-time API van Trail:Datum Tijd .