tl;dr
myPreparedStatement
.setObject(
… , // Specify which placeholder `?` in your SQL statement.
OffsetDateTime.now( ZoneOffset.UTC ) // Capture the current moment as seen in the wall-clock time of UTC (an offset-from-UTC of zero).
) ;
Évitez les anciennes classes de date et d'heure
Vous utilisez de terribles classes date-heure qui ont été supplantées il y a des années par le java.time Des classes.
Ne jamais utiliser Date
ou Timestamp
.
UTC
Capturez le moment actuel, en UTC. La plupart des bases de données stockent un moment en UTC. Et généralement, vous devriez faire la plupart de votre logique métier, du débogage, de la journalisation, du stockage et de l'échange de données en UTC.
OffsetDateTime
Représentez un moment avec un décalage par rapport à UTC en utilisant le bien nommé OffsetDateTime
classer.
Nous voulons UTC lui-même, ou un décalage de zéro. Nous pouvons utiliser une constante pour cela, ZoneOffset.UTC
.
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ) ;
JDBC 4.2
Depuis JDBC 4.2, nous pouvons échanger directement java.time objets avec la base de données.
Pour enregistrer ce moment dans une colonne d'un type de données semblable au standard SQL TIMESTAMP WITH TIME ZONE
:
myPreparedStatement.setObject( … , odt ) ;
Récupération :
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ZonedDateTime
Pour présenter ce moment récupéré à l'utilisateur, vous souhaiterez peut-être vous adapter au fuseau horaire attendu/souhaité de l'utilisateur.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
Ne vous fiez jamais au fuseau horaire par défaut
Notez dans le code ci-dessus que nous avons toujours spécifié le décalage ou la zone souhaité/attendu.
Si vous ne le spécifiez pas, un décalage ou une zone est implicitement appliqué de manière silencieuse. Mieux vaut spécifier explicitement vos intentions car les valeurs par défaut actuelles de votre JVM, de votre base de données et de votre système d'exploitation hôte ne sont pas entre vos mains en tant que programmeur. Ce qui signifie que le code reposant sur la valeur par défaut aura un comportement différent lors de l'exécution.
Java 6 et 7
Le même homme, Stephen Colebourne, qui dirige JSR 310 et le java.time implémentation, ainsi que le fameux Joda-Time projet, dirige également un autre projet, ThreeTen-Backport . La plupart du temps java.time la fonctionnalité est rétroportée vers Java 6 et 7 dans cette bibliothèque, avec une API presque identique.
Alors faites tout votre travail dans des classes de back-port. Puis, au dernier moment, convertissez vers/depuis java.sql.Timestamp
via DateTimeUtils
classer.
Ces méthodes de conversion utilisent principalement Instant
objets. Un Instant
est un moment en UTC, toujours en UTC. Vous pouvez ajuster à partir de votre OffsetDateTime
vers UTC en extrayant un Instant
. L'Instant
class est la classe de base du bloc de construction dans java.time , avec OffsetDateDate
avoir plus de flexibilité, comme des modèles de formatage alternatifs lors de la génération d'une chaîne. Mais à la fois Instant
et OffsetDateTime
représenter un moment, un point sur la chronologie.
Instant instant = odt.toInstant() ;
java.sql.Timestamp ts = org.threeten.bp.DateTimeUtils.toSqlTimestamp( instant ) ;
Dans l'autre sens, récupérer un Timestamp
de votre base de données, puis conversion immédiate en Instant
.
java.sql.Timestamp ts = myResultSet.getTimestamp( … ) ;
Instant instant = org.threeten.bp.DateTimeUtils.toInstant( ts ) ;
À propos de java.time
Le java.time
framework est intégré à Java 8 et versions ultérieures. Ces classes supplantent l'ancien héritage gênant
les classes date-heure telles que java.util.Date
, Calendar
, &SimpleDateFormat
.
Le Joda-Time projet, maintenant en mode maintenance , conseille la migration vers java.time cours.
Pour en savoir plus, consultez le tutoriel Oracle . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 310 .
Vous pouvez échanger java.time objets directement avec votre base de données. Utilisez un pilote JDBC
conforme à JDBC 4.2
ou plus tard. Pas besoin de chaînes, pas besoin de java.sql.*
cours.
Où obtenir les classes java.time ?
- Java SE 8
, Java SE 9
, Java SE 10
, Java SE 11
, et versions ultérieures - Partie de l'API Java standard avec une implémentation groupée.
- Java 9 ajoute quelques fonctionnalités et corrections mineures.
- Java SE 6
et Java SE 7
- La plupart du temps java.time la fonctionnalité est rétroportée vers Java 6 et 7 dans ThreeTen-Backport .
- Android
- Versions ultérieures des implémentations de bundles Android de java.time cours.
- Pour les versions antérieures d'Android (<26), le ThreeTenABP le projet adapte ThreeTen-Backport (mentionné ci-dessus). Voir Comment utiliser ThreeTenABP… .
Le ThreeTen-Extra
Le projet étend java.time avec des classes supplémentaires. Ce projet est un terrain d'essai pour d'éventuels futurs ajouts à java.time. Vous pouvez trouver ici des classes utiles telles que Interval
, YearWeek
, YearQuarter
, et plus
.