Mysql
 sql >> Base de données >  >> RDS >> Mysql

Problèmes de fuseau horaire Java MySQL Timestamp

Jordan, en fait tu as eu la bonne idée. Le problème est qu'il y a un bogue dans le pilote MySQL JDBC et que l'argument Calendar est complètement ignoré par défaut. Regardez le code source de PreparedStatement pour vraiment voir ce qui se passe.

Notez qu'il formate l'horodatage en utilisant le fuseau horaire de la JVM. Cela ne fonctionnera que si votre JVM utilise le fuseau horaire UTC. L'objet Calendrier est complètement ignoré.

this.tsdf = new SimpleDateFormat("''yyyy-MM-dd HH:mm:ss''", Locale.US);
timestampString = this.tsdf.format(x);

Pour que MySQL utilise l'argument Calendar, vous devez désactiver l'ancien code de date/heure avec l'option de connexion suivante :

useLegacyDatetimeCode=false

Vous pouvez donc l'utiliser lors de la connexion à la base de données comme ceci :

String url = "jdbc:mysql://localhost/tz?useLegacyDatetimeCode=false"

Si vous désactivez l'ancien code datetime à l'aide de la ligne ci-dessus, il rendra votre horodatage dans le fuseau horaire du calendrier cible :

if (targetCalendar != null) {
    targetCalendar.setTime(x);
    this.tsdf.setTimeZone(targetCalendar.getTimeZone());

     timestampString = this.tsdf.format(x);
} else {
    this.tsdf.setTimeZone(this.connection.getServerTimezoneTZ());
    timestampString = this.tsdf.format(x);
}

Il est assez facile de voir ce qui se passe ici. Si vous transmettez un objet Calendar, il l'utilisera lors du formatage des données. Sinon, il utilisera le fuseau horaire de la base de données pour formater les données. Étrangement, si vous passez dans un calendrier, il réglera également l'heure sur la valeur d'horodatage donnée (ce qui semble inutile).