java.time
Avec la sortie de Java SE 8 en mars 2014, l'ancienne API Date-Time obsolète et sujette aux erreurs (java.util
Types date-heure et leur type de formatage, SimpleDateFormat
etc.) a été remplacé par java.time
, l'API date-heure moderne. Le tableau suivant
décrit le mappage des types SQL ANSI avec java.time
type :
SQL ANSI | Java SE 8 |
---|---|
DATE | DateLocale |
HEURE | Heure Locale |
HORODATAGE | DateHeureLocale |
HEURE AVEC FUSEAU HORAIRE | OffsetTime |
HORODATAGE AVEC FUSEAU HORAIRE | OffsetDateTime |
Notez que ZonedDateTime
et Instant
ne sont pris en charge par aucun pilote JDBC alors que certains pilotes, par ex. PostgreSQL ne prend pas non plus en charge OffsetTime
/ TIME [ WITHOUT TIMEZONE ]
. Notez également que tous les OffsetDateTime
les instances devront être en UTC (avoir un décalage de 0). C'est parce que le backend les stocke en UTC.
Comment l'utiliser dans JDBC ?
Ci-dessous est un exemple de code pour insérer le OffsetDateTime
actuel en UTC, dans columnfoo
(qui est de TIMESTAMP WITH TIMEZONE
taper):
OffsetDateTime odt = Instant.now().atOffset(ZoneOffset.UTC);
PreparedStatement st = conn.prepareStatement("INSERT INTO mytable (columnfoo) VALUES (?)");
st.setObject(1, odt);
st.executeUpdate();
st.close();
Un Instant
représente un point instantané sur la chronologie et est indépendant d'un fuseau horaire, c'est-à-dire qu'il a un décalage de fuseau horaire de +00:00
heures.
Ci-dessous est un exemple de code pour récupérer un OffsetDateTime
de 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();
Juste au cas où vous auriez besoin de convertir un OffsetDateTime
dans un autre avec un décalage différent :
Il existe plusieurs façons de le faire, mais j'utilise principalement OffsetDateTime#withOffsetSameInstant
, pour convertir un OffsetDateTime
dans un autre avec un décalage de fuseau horaire différent, par exemple
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);
}
}
Sortie :
2021-05-29T13:36:15.258076Z
2021-05-29T15:36:15.258076+02:00
2021-05-29T14:36:15.258076+01:00
Quelques points liés au code donné ci-dessus :
- Le
Z
dans la sortie est le indicateur de fuseau horaire pour un décalage de fuseau horaire nul. Il signifie zoulou et spécifie leEtc/UTC
fuseau horaire (qui a le décalage horaire de+00:00
heures). - Le code convertit
odt
en deux instances deOffsetDateTime
- chacun d'une manière différente. La première instance est avec un décalage de fuseau horaire fixe de+02:00
heures alors que le second est avec le décalage horaire de la JVM. Notez que le décalage horaire d'un lieu observant DST change selon l'heure d'été/d'hiver. Par conséquent, si un lieu observe l'heure d'été, au lieu d'utiliser un décalage de fuseau horaire fixe, par ex.+02:00
les heures; nous devrions l'obtenir à partir de l'API. - Le fuseau horaire de ma JVM est
Europe/London
et actuellement son décalage est+01:00
heures.
En savoir plus sur l'API date-heure moderne de Trail :Date Time .