4 votes

date heure correcte dans l'application mais fausse dans mysql [fuseau horaire].

Problème : L'heure est correcte dans le serveur d'application, mais incorrecte dans la base de données.

Je suis en Chine, le fuseau horaire est UTC+8 J'utilise hibernate. La définition de l'entité est la suivante (langage : Scala)

class CargoJournal {
    @Type(`type`="org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime")
    var deliverTime: LocalDateTime = _

    @Temporal(TemporalType.TIMESTAMP)
    @Column(nullable=false)
    var logDate:Date = _
}

J'ouvre le journal d'hibernation, je vois ce qui suit dans mon serveur d'application. L'heure actuelle est Thu Sep 13 11:08:44 CST 2012

insert into wms_history_cargo_journal (deliver_time, log_date)
binding parameter [1] as [TIMESTAMP] - 2012-09-13 11:08:44.25
binding parameter [2] as [TIMESTAMP] - Thu Sep 13 11:08:44 CST 2012

Dans mon serveur de base de données :

mysql> select timediff(now(),convert_tz(now(),@@session.time_zone,'+00:00'));
+----------------------------------------------------------------+
| timediff(now(),convert_tz(now(),@@session.time_zone,'+00:00')) |
+----------------------------------------------------------------+
| 08:00:00                                                       |
+----------------------------------------------------------------+

Le fuseau horaire de mysql est donc correct. UTC+8

Après avoir effectué une sélection dans mysql :

mysql> SELECT deliver_time, log_date FROM wms_history_cargo_journal;
+---------------------+---------------------+
| deliver_time        | log_date            |
+---------------------+---------------------+
| 2012-09-13 11:08:44 | 2012-09-13 03:08:44 |
+---------------------+---------------------+

La date d'enregistrement est erronée !

1voto

amorfis Points 4456

Quels sont les types de colonnes dans MySQL ? Je pense qu'il s'agit de DATETIME. Ce type ne stocke pas un "moment dans le temps", mais une "heure sur l'horloge", ce qui peut signifier des moments différents dans des fuseaux horaires différents.

Lorsque le pilote MySQL écrit java.util.Date dans la colonne DATETIME, il doit choisir un fuseau horaire pour écrire "l'heure sur l'horloge", car la même java.util.Date peut signifier une heure différente dans différents fuseaux horaires. Il enregistre l'heure dans le fuseau horaire local du serveur MySQL.

LocalDateTime n'a pas ce problème, parce qu'il est comme DATETIME. Il représente l'heure sur une horloge, et non un moment dans le temps, de sorte que l'année/le mois/le jour/l'heure/la minute/la seconde sont simplement stockés dans la base de données. Remarquez que dans le journal d'hibernation, LocalDateTime est donné tel quel, alors qu'il y a un fuseau horaire ("CST") à côté de Date.

En règle générale, il est préférable de toujours stocker l'heure en UTC, et donc d'utiliser DateTime, et non Date ou LocalDateTime. DateTime avec le convertisseur jadira stocke/lit toujours DATETIME en UTC.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X