web-dev-qa-db-fra.com

Comment changer le fuseau horaire MySQL dans une connexion à une base de données utilisant Java?

MySQL fonctionne avec le fuseau horaire "GMT + 8", mais Tomcat avec "GMT". Lorsque je sauvegarde datetime dans ma base de données, tout semble bien se passer, mais lorsque je vérifie la valeur datetime dans la base de données, la valeur "GMT" est affichée.

De plus, lorsque j'essaie d'obtenir la valeur de la base de données, celle-ci a été modifiée. La valeur dans la base de données est considérée comme "GMT + 8". Java est donc remplacé par "GMT".

J'ai défini l'URL de connexion comme ceci:

useTimezone=true&serverTimezone=GMT

mais ça ne marche pas.

31
Xilang

useTimezone est une solution de contournement plus ancienne. L'équipe MySQL a récemment réécrit le code setTimestamp/getTimestamp, mais il ne sera activé que si vous définissez le paramètre de connexion useLegacyDatetimeCode = false et que vous utilisez la dernière version du connecteur JDBC mysql. Donc par exemple:

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

Si vous téléchargez le code source de mysql-connector et regardez setTimestamp, il est très facile de voir ce qui se passe:

Si legacy date time code = false, newSetTimestampInternal (...) est appelé. Ensuite, si le calendrier transmis à newSetTimestampInternal est NULL, votre objet de date est formaté dans le fuseau horaire de la base de données:

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

Il est très important que Calendar soit null - assurez-vous donc que vous utilisez:

setTimestamp(int,Timestamp).

... PAS setTimestamp (int, Horodatage, Calendrier).

Il devrait être évident maintenant comment cela fonctionne. Si vous construisez une date: le 5 janvier 2011 à 15 h 00 en Amérique/Los_Angeles (ou le fuseau horaire de votre choix) à l'aide de Java.util.Calendar et appelez setTimestamp (1, myDate), votre date sera prise, utilisez SimpleDateFormat pour le formater dans le fuseau horaire database. Donc, si votre base de données se trouve dans America/New_York, elle construira la chaîne '2011-01-05 6:00:00' à insérer (puisque NY est en avance de 3 heures sur LA).

Pour récupérer la date, utilisez getTimestamp (int) (sans le calendrier). Une fois encore, il utilisera le fuseau horaire de la base de données pour créer une date.

Remarque: Le fuseau horaire du serveur Web n'a plus aucune importance! Si vous ne définissez pas useLegacyDatetimecode sur false, le fuseau horaire du serveur Web est utilisé pour le formatage, ce qui crée beaucoup de confusion.


Remarque:

Il est possible que MySQL se plaint que le fuseau horaire du serveur soit ambigu. Par exemple, si votre base de données est configurée pour utiliser EST, il peut y avoir plusieurs fuseaux horaires EST possibles en Java. Vous pouvez donc clarifier cela pour mysql-connector en lui indiquant exactement le fuseau horaire de la base de données:

String url =
 "jdbc:mysql://localhost/mydb?useLegacyDatetimeCode=false&serverTimezone=America/New_York";

Vous ne devez le faire que si cela se plaint.

62
nogridbag

JDBC utilise une "adresse URL de connexion". Vous pouvez ainsi échapper "+" à "% 2B", c'est-à-dire

useTimezone=true&serverTimezone=GMT%2B8
0
Jay