tl; dr
String sql = "SELECT CURRENT_TIMESTAMP ;
…
OffsetDateTime odt = myResultSet.getObject( 1 , OffsetDateTime.class ) ;
Évitez de dépendre du système d'exploitation hôte ou de la JVM pour le fuseau horaire par défaut
Je vous recommande d'écrire tout votre code pour indiquer explicitement le fuseau horaire souhaité / attendu. Vous n'avez pas besoin de dépendre du fuseau horaire par défaut actuel de la JVM. Et sachez que le fuseau horaire par défaut actuel de la JVM peut changer à tout moment pendant l'exécution, avec n'importe quel code dans n'importe quel thread de n'importe quel appel d'application TimeZone.setDefault
. Un tel appel affecte immédiatement toutes les applications de cette JVM.
java.time
Certaines des autres réponses étaient correctes, mais sont maintenant dépassées. Les terribles classes de date-heure fournies avec les premières versions de Java étaient défectueuses, écrites par des personnes qui ne comprenaient pas les complexités et les subtilités de la gestion de la date-heure.
Les anciennes classes date-heure ont été remplacées par les classes java.time définies dans JSR 310.
Pour représenter un fuseau horaire, utilisez ZoneId
. Pour représenter un décalage par rapport à UTC, utilisez ZoneOffset
. Un décalage est simplement un nombre d'heures-minutes-secondes en avant ou en arrière du méridien principal. Un fuseau horaire, c'est bien plus. Un fuseau horaire est une histoire des changements passés, présents et futurs du décalage utilisé par les habitants d'une région particulière.
Je dois forcer toutes les opérations liées au temps à GMT / UTC
Pour un décalage de zéro heure-minute-seconde, utilisez la constante ZoneOffset.UTC
.
Instant
Pour capturer le moment actuel en UTC, utilisez un fichier Instant
. Cette classe représente un moment en UTC, toujours en UTC par définition.
Instant instant = Instant.now() ; // Capture current moment in UTC.
ZonedDateTime
Pour voir ce même moment à travers l'heure de l'horloge murale utilisée par les habitants d'une région particulière, ajustez-vous dans un fuseau horaire. Même moment, même point sur la chronologie, heure d'horloge murale différente.
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
Base de données
Vous mentionnez une base de données.
Pour récupérer un instant de la base de données, votre colonne doit être d'un type de données similaire au standard SQL TIMESTAMP WITH TIME ZONE
. Récupérez un objet plutôt qu'une chaîne. Dans JDBC 4.2 et versions ultérieures, nous pouvons échanger des objets java.time avec la base de données. Le OffsetDateTime
est requis par JDBC, tandis que Instant
& ZonedDateTime
sont facultatifs.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Dans la plupart des bases de données et des pilotes, je suppose que vous obtiendrez le moment comme vu en UTC. Mais sinon, vous pouvez régler de deux manières:
- Extraire un
Instant
: odt.toInstant()
- Ajuster à partir du décalage donné à un décalage de zéro: OffsetDateTime odtUtc = odt.withOffsetSameInstant (ZoneOffset.UTC); `.
À propos de java.time
Le framework java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent les anciens gênants hérités des classes date-heure tels que java.util.Date
, Calendar
, et SimpleDateFormat
.
Pour en savoir plus, consultez le didacticiel Oracle . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 310 .
Le projet Joda-Time , désormais en mode maintenance , conseille la migration vers les classes java.time .
Vous pouvez échanger des objets java.time directement avec votre base de données. Utilisez un pilote JDBC compatible avec JDBC 4.2 ou version ultérieure. Pas besoin de chaînes, pas besoin de java.sql.*
classes.
Où obtenir les classes java.time?