Comment changer le fuseau horaire mysql dans une connexion java

Mysql run au GMT+8 mais tomcat run au GMT. lorsque vous enregistrez datetime dans la base de données, vous avez l'air d'Exécuter ok, lorsque je vérifie la valeur datetime dans DB, je vois la valeur GMT. Mais quand j'essaie d'obtenir la valeur de DB,la valeur est changée, il semble que la valeur de DB soit prise comme GMT+8, donc java change la valeur en GMT.

j'essaie de définir l'url de connexion Ajouter

useTimezone=true&serverTimezone=GMT

mais ne fonctionne pas

26
demandé sur Xilang 2011-09-30 08:29:08

1 réponses

useTimezone est une solution plus ancienne. L'équipe MySQL a réécrit le code setTimestamp/getTimestamp assez récemment, 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. Ainsi, par exemple:

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

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

si utiliser l'ancien code de date heure = false, newSetTimestampInternal(...) est appelée. Ensuite, si le calendrier passé à newSetTimestampInternal est nul, votre objet 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 le calendrier soit null - alors assurez-vous que vous utilisez:

setTimestamp(int,Timestamp).

... Pas setTimestamp (int,Timestamp,Calendar).

Il devrait être évident maintenant comment cela fonctionne. Si vous construisez une date: janvier 5, 2011 3: 00 AM en Amérique / Los_Angeles (ou quel que soit le fuseau horaire que vous voulez) à l'aide de java.util.Calendrier et appelez setTimestamp(1, madate), puis il va prendre votre date, l'utilisation SimpleDateFormat la formater dans le fuseau horaire de la base de données. Donc, si votre DB est en Amérique/New_York, il construira la chaîne de caractères '2011-01-05 6:00:00' à insérer (puisque NY est en avance de LA de 3 heures).

pour récupérer la date, utilisez getTimestamp(int) (sans le calendrier). Encore une fois, il utilisera le fuseau horaire de la base de données pour construire une date.

Remarque: le le fuseau horaire de webserver n'est plus pertinent maintenant! si vous ne définissez pas uselegacydatetimecode à false, le fuseau horaire du serveur web est utilisé pour le formatage - ajoutant beaucoup de confusion.


Remarque:

il est possible que MySQL mon se plaignent que le fuseau horaire du serveur est ambigu. Par exemple, si votre base de données est paramétrée pour utiliser EST, il pourrait y avoir plusieurs fuseaux horaires EST possibles en Java, donc vous pouvez clarifier ceci pour mysql-connector en lui disant exactement ce que le le fuseau horaire de la base de données est:

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

vous n'avez besoin de le faire que s'il se plaint.

56
répondu nogridbag 2016-06-28 02:36:47