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
Zdans la sortie est le indicateur de fuseau horaire pour un décalage de fuseau horaire nul. Il signifie zoulou et spécifie leEtc/UTCfuseau horaire (qui a le décalage horaire de+00:00heures). - Le code convertit
odten 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:00heures 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:00les heures; nous devrions l'obtenir à partir de l'API. - Le fuseau horaire de ma JVM est
Europe/Londonet actuellement son décalage est+01:00heures.
En savoir plus sur l'API date-heure moderne de Trail :Date Time .