Pilote MySQL JDBC 5.1.33 - Problème de fuseau horaire


361

Quelques antécédents:

J'ai une application Web Java 1.6 exécutée sur Tomcat 7. La base de données est MySQL 5.5. Auparavant, j'utilisais le pilote Mysql JDBC 5.1.23 pour me connecter à la base de données. Tout fonctionnait. J'ai récemment mis à niveau le pilote Mysql JDBC 5.1.33. Après la mise à niveau, Tomcat lançait cette erreur lors du démarrage de l'application.

WARNING: Unexpected exception resolving reference
java.sql.SQLException: The server timezone value 'UTC' is unrecognized or represents more than one timezone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc timezone value if you want to utilize timezone support.

Pourquoi cela arrive-t-il?


1
À quoi ressemble votre URL JDBC?
David Levesque

Vérifiez ma réponse stackoverflow.com/a/44720416/4592448 . Je pense que sa meilleure réponse)
Fortran

Réponses:


676

Apparemment, pour que la version 5.1.33 du pilote MySQL JDBC fonctionne avec le fuseau horaire UTC, il faut spécifier serverTimezoneexplicitement la chaîne de connexion.

jdbc:mysql://localhost/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC

4
Selon les documents, useJDBCCompliantTimezoneShift n'a aucun effet lors de l'utilisation de useLegacyDatetimeCode = false. Par conséquent, il n'est pas nécessaire là-bas ...
matof

24
Cela résout mon erreur. Remarque supplémentaire, échappez au & avec & amp; dans le fichier persistence.xml: <property name = "javax.persistence.jdbc.url" value = "jdbc: mysql: // localhost / test? useUnicode = true & amp; useJDBCCompliantTimezoneShift = true & amp; useLegacyDatetimeCode = false & amp; serverTimezone = UTC"
pdem

5
Ce n'est pas correct. Le point d'utilisationLegacyDatetimeCode = false ne doit pas spécifier serverTimezone afin que le client corrige les différences de fuseau horaire. C'est un bug dans cette version du client MySQL.
antgar9

2
Cette solution ruine le fuseau horaire sauf pour GMT. Je pense que la bonne solution est sous
DuncanSungWKim

1
fonctionne avec 8.0.17. Arrivé avec une nouvelle installation MySQL. Je ne peux pas croire que ce bug n'a pas été corrigé après tant d'années.
Tilman Hausherr

101

J'ai résolu ce problème en configurant MySQL.

SET GLOBAL time_zone = '+3:00';


6
si vous utilisez fuseau horaire MSK il est +3, vous pouvez utiliser folowing comme adresse db: jdbc:mysql://localhost/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Europe/Moscow. Il semble que mysql-connector ne comprenne pas les noms courts de fuseau horaire.
babay

2
Que faites-vous lorsque l'heure d'été change l'heure?
isapir

3
Avec mysql 8.0, vous pouvez appeler "set persist time_zone = '+00: 00';" pour le définir sur UTC de manière persistante, sans avoir besoin de modifier my.cnf ou de redémarrer le serveur. Voir mysqlserverteam.com/…
ccleve

Si vous le définissez via une requête SQL manuelle unique, ce paramètre reviendrait à ce que la valeur d'origine était après un redémarrage de la base de données.
CBA110

fonctionne - n'oubliez pas de modifier votre chaîne de fuseau horaire local à la place de +3 SET GLOBAL time_zone = '+3: 00';
Pravin

61

Après avoir lu plusieurs articles sur ce sujet, testé différentes configurations et basé sur quelques aperçus de ce fil de bogue mysql c'est ce que j'ai compris:

  • le fuseau horaire du serveur est important notamment pour convertir les dates stockées dans la base de données au fuseau horaire du serveur d'application. il y a d'autres implications, mais c'est la plus notable
  • Systèmes de fuseau horaire GMT x UTC. Le GMT a été conçu à la fin du XIXe siècle et peut être décalé entre l'heure standard et l'heure d'été. cette propriété pourrait conduire à une situation où le serveur de base de données passe à l'heure d'été et l'application ne le remarque pas (il y a peut-être d'autres complications mais je n'ai pas cherché plus loin). L'UTC ne varie pas dans le temps (il se situe toujours à environ 1 seconde du temps solaire moyen à 0 ° de longitude).
  • La définition de serverTimeZone a été introduite dans les versions 5.1 des connecteurs mysql jdbc. jusqu'à la version 8, il pouvait être ignoré useLegacyDatetimeCode=true, ce qui, conjointement avec, useJDBCCompliantTimezoneShift=trueferait en sorte que l'application obtienne le fuseau horaire de la base de données à chaque connexion. Dans ce mode, les fuseaux horaires GMT tels que «British Summer Time» seraient convertis au format interne java / JDBC. De nouveaux fuseaux horaires pourraient être définis dans un fichier .properties tel que celui-ci
  • À partir de la version 8 du pilote jdbc, la correspondance automatique de l'heure ( useJDBCCompliantTimezoneShift) et le format d'heure hérité ( useLegacyDatetimeCode) ont été supprimés ( voir le changelog du connecteur mysql jdbc ). donc la définition de ces 2 paramètres n'a aucun effet car ils sont complètement ignorés (la nouvelle valeur par défaut estuseLegacyDateTimeCode=false )
  • De cette manière, le réglage serverTimezoneest devenu obligatoire si l'un des fuseaux horaires (serveurs d'application / de base de données) n'est pas au format 'UTC + xx' ou 'GMT + xx'
  • La définition de l'heure du serveur sur UTC n'a aucun impact (par exemple avec jdbc:mysql://localhost:3306/myschema?serverTimezone=UTC, même si vos serveurs d'application / de base de données ne se trouvent pas dans ce fuseau horaire. L'important est que la chaîne de connexion de l'application + la base de données soient synchronisées avec le même fuseau horaire. En d'autres termes , simplement définir serverTimezone = UTC avec un fuseau horaire différent sur le serveur de base de données décalera toutes les dates extraites de la base de données
  • Le fuseau horaire par défaut de MySQL peut être défini sur UTC + 0 avec les fichiers my.ini ou my.cnf (windows / linux respectivement) en ajoutant la ligne default-time-zone='+00:00'(détails dans ce post StackOverflow )
  • Les bases de données configurées sur AWS (services Web d'Amazon) se voient automatiquement attribuer l'heure UTC + 0 par défaut ( voir la page d'aide d'AWS ici )

1
Belle réponse, merci. Les différentes balles sont toutes utiles. Je suis allé avec la suggestion de mettre un default-time-zone = '+00:00'dans le /usr/local/etc/my.cnffichier homebrew . Il semble que les espaces autour de l ' =soient importants mais vous pouvez donc modifier cette puce pour les inclure.
Mark Edington

51

Si vous utilisez Maven, vous pouvez simplement définir une autre version du connecteur MySQL (j'ai eu la même erreur, j'ai donc changé de 6.0.2 à 5.1.39) dans pom.xml:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.39</version>
</dependency>

Comme indiqué dans une autre réponse, ce problème a été corrigé dans les versions 6.0.3 ou supérieures, vous pouvez donc utiliser la version mise à jour:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>6.0.3</version>
</dependency>

Maven reconstruira automatiquement votre projet après avoir enregistré le pom.xmlfichier.


2
Pour ceux qui ont téléchargé mysql-connector-java / 6 -> il suffit de télécharger par exemple mysql-connector-java / 5.1.20 et cela devrait fonctionner. Merci!
Combinez

6
le déclassement doit être évité. aussi, ce n'est pas fixe avec 6.0.6encore. préférable d'utiliser la solution ci-dessus
phil294

j'obtiens la même erreur même avec le dernier pot [mysql-connector-java-6.0.5.jar: 6.0.5]
user2478236

18
Je l'ai même au 8.0.12
Robert Niestroj

13
8.0.13 donne la même erreur. 5.1.47 fonctionne cependant pour moi.
localhost

36

La chaîne de connexion doit être définie comme ceci:

jdbc:mysql://localhost/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC

Si vous définissez la connexion dans un xmlfichier ( par exemple persistence.xml, standalone-full.xml, etc ..), au lieu de &vous devez utiliser &amp;ou utiliser un CDATAbloc.


1
Ce n'est pas correct. Le point d'utilisationLegacyDatetimeCode = false ne doit pas spécifier serverTimezone afin que le client corrige les différences de fuseau horaire.
antgar9

Cela a fonctionné pour moi en me connectant à MySQL 5.7 avec phpStorm 2019.1.4.
moult86

29

Il s'agit d'un bogue dans mysql-connector-java de la version 5.1.33 à 5.1.37. Je l'ai signalé ici: http://bugs.mysql.com/bug.php?id=79343

Modifié: cela a été corrigé depuis mysql-connector-java 5.1.39

Il s'agissait d'une faute de frappe dans la classe TimeUtil de la méthode loadTimeZoneMappings qui déclenche un fichier NPE localisant /com/mysql/jdbc/TimeZoneMapping.properties. Si vous regardez le code, le fichier doit se trouver dans le chargeur de classe TimeUtil, pas TimeZone:

TimeUtil.class.getResourceAsStream(TIME_ZONE_MAPPINGS_RESOURCE);

Le paramètre useLegacyDatetimeCode permet de corriger automatiquement la différence entre les fuseaux horaires client et serveur lors de l'utilisation des dates. Cela vous aide donc à ne pas avoir à spécifier de fuseaux horaires dans chaque partie. Bien que l'utilisation du paramètre serverTimeZone soit une solution de contournement, et pendant ce temps, le correctif est publié, vous pouvez essayer de mieux corriger le code par vous-même comme je l'ai fait.

  • S'il s'agit d'une application autonome, vous pouvez simplement essayer d'ajouter une classe com / mysql / jdbc / TimeUtil corrigée à votre code et faire attention à l'ordre de chargement des fichiers. Cela peut aider: https://owenou.com/2010/07/20/patching-with-class-shadowing-and-maven.html

  • S'il s'agit d'une application Web, la solution la plus simple consiste à créer votre propre mysql-connector-java-5.1.37-patched.jar, en remplaçant le .class directement dans le bocal d'origine.


Doux, merci d'avoir signalé cela. Heureux que quelqu'un ait pu identifier le bug. Savez-vous quand le correctif sera publié?
bluecollarcoder

La solution que vous proposez est excellente, mais je pense que modifier la source du pilote et gérer la dépendance Maven est probablement trop ennuyeux pour la plupart des gens.
bluecollarcoder

4
@Gili Ce problème n'est pas résolu à partir de la version 6.0.6
Imme22009

6
Le bug est toujours présent dans la version 8.0.11
John Little le

3
@JohnLittle J'ai aussi ce problème dans 8.0.15, mais il n'est plus causé par le bogue. Les fuseaux horaires sont chargés correctement, mais CET et CEST (ces fuseaux horaires me causent des problèmes) ne sont inclus ni dans TimeZone.getAvailableIDs()ni dans, TimeZoneMapping.propertiesdonc cette solution n'aidera pas ici. La solution serait probablement mise en place commeserverTimezone=Europe/Berlin
JPT

29

J'ai résolu de mettre la chaîne de connexion ci-dessous dans l'URL

jdbc:mysql://localhost:3306/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC

1
Ce n'est pas correct. Le point d'utilisationLegacyDatetimeCode = false ne doit pas spécifier serverTimezone afin que le client corrige les différences de fuseau horaire.
antgar9

25

Cela a fonctionné pour moi simplement en ajoutant serverTimeZone = UTC sur application.properties.
spring.datasource.url=jdbc:mysql://localhost/db?serverTimezone=UTC


22
  1. J'ai ajouté dans le fichier de configuration mysql dans la section [mysqld]

    default_time_zone='+03:00'
  2. Et redémarrez le serveur mysql:

    sudo service mysql restart

+03: 00 mon fuseau horaire UTC.

Chemin d'accès au fichier de configuration sur mon os ubuntu 16.04:

/etc/mysql/mysql.conf.d/mysqld.cnf

AVERTISSEMENT: SI VOTRE FUSEAU HORAIRE A DES HEURES D'ÉTÉ ET D'HIVER. VOUS DEVEZ MODIFIER L'UTC DANS LA CONFIGURATION SI VOUS CHANGEZ D'HEURE. DEUX FOIS DANS L'ANNÉE (HABITUELLEMENT) OU DÉFINIR CRONTAB AVEC SUDO.

Ma connexion URL jdbc:

"jdbc:mysql://localhost/java"

1
Le redémarrage de Mysql est fondamentalement un non-démarreur dans presque tous les cas d'utilisation de la production. Cela devient encore plus problématique lorsque des réplications sont impliquées.
bluecollarcoder

@bluecollarcoder Nécessite d'ajouter uniquement dans la section [mysqld]. Ou ajoutez la section [mysqld] si ce n'est pas le cas. Exemple ma configuration pastebin.com/j4F7t2KS
Fortran

1
J'ai mis à jour / etc / localtime de mon serveur Linux de / usr / share / zoneinfo / US / Pacific vers / usr / share / zoneinfo / America / Los_Angeles puis redémarré le service mysql et cela a résolu le problème pour moi.
vinnyjames

Dans mon cas pour la syntaxe fournie, il y avait une erreur lors du redémarrage, et la syntaxe correcte était: à la default-time-zone='+03:00'place, selon cette réponse . Venant également de DBeaver.
wscourge

ce n'est pas approprié si vous devez dire à tous les développeurs de votre entreprise de modifier leur configuration MySQL :)
phéromix

16

J'ai le même problème et je l'ai résolu, ajoutez seulement "? ServerTimezone = UTC" à ma connexion de chaîne.

#

sinossi mon problème:

java.sql.SQLException: la valeur de fuseau horaire du serveur 'CEST' n'est pas reconnue ou représente plusieurs fuseaux horaires. Vous devez configurer le serveur ou le pilote JDBC (via la propriété de configuration serverTimezone) pour utiliser une valeur de fuseau horaire plus spécifique si vous souhaitez utiliser la prise en charge du fuseau horaire.

my dbDriver = com.mysql.jdbc.Driver

my jar = mysql-connector-java-8.0.12.jar

my java = 1.8

my tomcat = Apache Tomcat Version 8.5.32

my MySql server = MySql ver.8.0.12 

14

Le programme ci-dessus générera cette erreur de fuseau horaire.

Après le nom de votre base de données , vous devez ajouter ceci: ?useTimezone=true&serverTimezone=UTC. Une fois que vous avez terminé, votre code fonctionnera correctement.

Bonne chance :)



13

Tout ce dont nous avons besoin pour résoudre le problème serverTimezone:

String url = "jdbc:mysql://localhost:3306/db?serverTimezone=" + TimeZone.getDefault().getID()

Cela m'est arrivé aussi avec la dernière version 5.4.15. Mais corrigé avec ceci: l'ajout de "? ServerTimezone =" + TimeZone.getDefault (). GetID () "juste à côté de la base de données ur, résout les problèmes.
Tes

10

Vous pouvez utiliser le connecteur MySQL dans la dépendance Maven,

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.14</version>
</dependency>

Ensuite, vous devez définir les bons paramètres dans le application.propertiesfichier,

spring.datasource.url=jdbc:mysql://localhost:3306/UserReward?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.username=testuser
spring.datasource.password=testpassword
# MySQL driver
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect

9

J'utilise mysql-connector-java-8.0.13 et j'ai eu le même problème. J'ai créé ma base de données dans la console de ligne de commande et résolu ce problème en utilisant la solution de @Dimitry Rud sur la ligne de commande:

SET GLOBAL time_zone = '-6:00';

Je n'avais pas besoin de redémarrer quoi que ce soit, de régler l'heure et d'exécuter immédiatement mon code dans Eclipse, il se connectait sans problème.

Le bogue est censé être corrigé dans une ancienne version, mais je pense avoir eu cette erreur car après avoir créé la base de données dans la console, je n'ai pas réglé cela. Je n'utilise pas Workbench ni une autre application pour gérer cela plutôt que la console.


6

Depuis mysql workbench, exécutez les instructions sql suivantes:

  1. SET @@ global.time_zone = '+00: 00';
  2. SET @@ session.time_zone = '+00: 00';

avec les instructions sql suivantes, vérifiez si les valeurs ont été définies:

SELECT @@ global.time_zone, @@ session.time_zone;


2
Cela a fonctionné pour moi lorsque l'erreur en question est apparue lors de la tentative de connexion avec IntelliJ IDEA.
Faheem Hassan Zunjani

6

Cela a fonctionné pour moi.

sur DBeaver 6.0: accédez à Paramètres de connexion> Propriétés du pilote> Fuseau horaire du serveur> Définir UTC.

En outre, dans la configuration de démarrage de printemps, a dû définir la propriété ci-dessous.

jdbc: mysql: // localhost: /? serverTimezone = UTC


5

Apparemment, pour que la version 5.1.33 du pilote MySQL JDBC fonctionne avec le fuseau horaire UTC, il faut spécifier explicitement le serverTimezone dans la chaîne de connexion.

spring.datasource.url = jdbc:mysql://localhost:3306/quartz_demo?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC

3

J'avais aussi exactement le même problème dans LibreOffice Base. Je viens donc de spécifier un «fuseau horaire sans heure d'été» dans la chaîne de connexion.
** entrez la description de l'image ici **

J'ai essayé sans le "& serverTimezone = MST" mais cela a également échoué.

J'ai également essayé "& serverTimezone = MDT" et cela a échoué, donc pour une raison quelconque, il n'aime pas l'heure d'été!


3

J'ai eu le même problème lorsque j'essaie de travailler avec le projet Spring Boot sur Windows.

L'URL de la source de données doit être:

spring.datasource.url=jdbc:mysql://localhost/database?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC


3

Exécutez la requête ci-dessous vers mysql DB pour résoudre l'erreur

MariaDB [xxx> SET @@global.time_zone = '+00:00';
Query OK, 0 rows affected (0.062 sec)

MariaDB [xxx]> SET @@session.time_zone = '+00:00';
Query OK, 0 rows affected (0.000 sec)

MariaDB [xxx]> SELECT @@global.time_zone, @@session.time_zone;

3

J'ai une erreur similaire à la vôtre, mais ma valeur de fuseau horaire du serveur est 'Afr. centrale Ouest 'donc j'ai fait ces étapes:

MyError (sur IntelliJ IDEA Community Edition):

    InvalidConnectionAttributeException: The server time zone value 'Afr. centrale Ouest' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the 'serverTimezone' configuration property) to use a more specifc time zone value if you want to u....

J'ai rencontré ce problème lorsque j'ai mis à niveau mon serveur mysql vers SQL Server 8.0 (MYSQL80).

La solution la plus simple à ce problème est d'écrire simplement la commande ci-dessous dans votre MYSQL Workbench -

  SET GLOBAL time_zone = '+1:00'

La valeur après le fuseau horaire sera égale à GMT +/- Différence dans votre fuseau horaire. L'exemple ci-dessus concerne l'Afrique du Nord (GMT + 1: 00) / ou l'Inde (GMT + 5: 30). Cela résoudra le problème.

Entrez le code suivant dans votre MySQL Workbench et exécutez la requête

[lien source pour question / problème]

[lien source pour la réponse]

[Capture d'écran de la solution]


2
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/resultout? useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC","root",""))

C'est en fait la solution à ce problème, mais ne vous contentez pas de le copier-coller dans votre programme. Si vous venez de lire la ligne, vous trouverez «resultout», c'est le nom de ma base de données, et vous devez écrire le vôtre.

Il existe trois composants de chaîne, le premier est l'URL, le deuxième est le nom d'utilisateur et le troisième est le mot de passe. Dans le paragraphe ci-dessus, nous avons effacé, url. Les deuxième et troisième composants String comme dit votre nom d'utilisateur et votre mot de passe, vous devez les modifier en conséquence.

Merci


1

J'ai résolu ce problème sans aucun changement de code unique. passez simplement à l'heure du système et définissez le fuseau horaire. Dans mon cas, le fuseau horaire par défaut était UTC que j'ai changé pour mon fuseau horaire local. Après avoir redémarré tous les services, tout a fonctionné pour moi.


1

Je suis en retard, mais si vous rencontrez l'erreur suivante et utilisez la source de données (javax.sql.DataSource):

The server time zone value 'CEST' is unrecognized or represents more than one time zone.

Définissez la ligne suivante pour supprimer l'erreur:

MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setServerTimezone("UTC");

1

Dans mon cas, c'était un environnement de test et j'ai dû faire fonctionner une application existante sans aucun changement de configuration, et si possible sans aucun changement de configuration MySQL. J'ai pu résoudre le problème en suivant la suggestion de @vinnyjames et en changeant le fuseau horaire du serveur en UTC :

ln -sf /usr/share/zoneinfo/UTC /etc/localtime
service mysqld restart

Cela m'a suffi pour résoudre le problème.


1

J'ai ajouté la ligne suivante à mon /etc/mysql/my.cnffichier:

default_time_zone='+00:00'

Redémarrage du serveur MySQL:

systemctl restart mysql

Et cela fonctionne comme un charme.


1

La définition de l'heure du serveur sur UTC n'a aucun impact (par exemple avec jdbc:mysql://localhost:3306/myschema?serverTimezone=UTC, même si vos serveurs d'application / de base de données ne se trouvent pas dans ce fuseau horaire. L'important est que la chaîne de connexion de l'application + la base de données soient synchronisées avec le même fuseau horaire.

En d'autres termes, le simple fait de définir serverTimezone=UTCun fuseau horaire différent sur le serveur de base de données décale toutes les dates extraites de la base de données


0

D'accord avec la réponse @bluecollarcoder, mais il est préférable d'utiliser TimeZone.getDefault().getID();à la fin de la chaîne de connexion:

"jdbc:mysql://localhost/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=" + TimeZone.getDefault().getID();  

Dans ce cas, le Timezoneparamètre est automatiquement mis à jour en fonction du fuseau horaire de la machine locale.


Ce n'est pas correct. Le point d'utilisationLegacyDatetimeCode = false ne doit pas spécifier serverTimezone afin que le client corrige les différences de fuseau horaire.
antgar9

0

Modifiez simplement la chaîne de connexion avec le code suivant dans le fichier application.properties.


spring.datasource.url=jdbc:mysql://localhost:3301/Db?
   useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=
   false&serverTimezone=UTC
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.