web-dev-qa-db-fra.com

Pilote MySQL JDBC 5.1.33 - Problème de fuseau horaire

Quelques antécédents:

J'ai une application Web Java 1.6 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 a fonctionné. J'ai récemment mis à jour 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?

162
bluecollarcoder

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

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

Si vous utilisez Maven, vous pouvez simplement définir une autre version du connecteur MySQL (j'avais la même erreur, je suis donc passée 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 d'autres réponses, ce problème a été résolu 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 fichier pom.xml

C'est 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

Edited: Ce problème a été corrigé à partir de mysql-connector-Java 5.1.39

C'était une faute de frappe dans la classe TimeUtil de la méthode loadTimeZoneMappings qui soulevait un fichier NPE localisant le fichier /com/mysql/jdbc/TimeZoneMapping.properties. Si vous examinez le code, le fichier doit se trouver dans le chargeur de classes TimeUtil, et non dans 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 de dates. Cela vous évite donc de devoir spécifier des fuseaux horaires dans chaque partie. Bien que l'utilisation du paramètre serverTimeZone soit une solution de contournement, le correctif étant publié, vous pouvez essayer de mieux corriger le code vous-même, comme je l'ai fait.

  • S'il s'agit d'une application autonome, vous pouvez simplement essayer d'ajouter une classe corrigée avec com/mysql/jdbc/TimeUtil à votre code et soyez prudent Avec l'ordre de chargement du fichier jar. 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 fichier Mysql-connector-Java-5.1.37-patched.jar, en remplaçant directement le fichier .class Dans le fichier jar d'origine.

26
antgar9

La chaîne de connexion devrait ê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 fichier xml (comme persistence.xml, standalone-full.xml, etc.), au lieu de &, vous devez utiliser &amp; ou un bloc CDATA.

23
Alireza Alallah

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

SET GLOBAL time_zone = '+3:00';

23
Dmitriy Rud

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

15
Ahmed AMMOURI

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

J'ai le même problème et je l'ai résolu d'ajouter uniquement "? ServerTimezone = UTC" à ma connexion chaîne.

sinossi mon problème:

Java.sql.SQLException: la valeur "CEST" du fuseau horaire du serveur 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 
12
felice de simone

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

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

Bonne chance :)

10
Aathil Ahamed
  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 EST ÉTÉ ET HIVER. VOUS DEVEZ CHANGER L'UTC DANS CONFIG SI LE CHANGEMENT D'HEURE. DEUX fois par an (habituellement) OR SET CRONTAB AVEC SUDOO.

Mon url connexion jdbc: 

"jdbc:mysql://localhost/Java"
5
Fortran

À partir de 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;

4
toof06

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 fichier application.properties,

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
4
Arefe

J'ai eu le même problème lorsque j'essaie de travailler avec le projet de démarrage de printemps 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
Berkay Ernalbant

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 @Dimitry Rud's solution sur la ligne de commande:

SET GLOBAL time_zone = '-6:00';

Je n'avais besoin de rien redémarrer, de régler l'heure et d'exécuter immédiatement mon code dans Eclipse, cela ne posait aucun problème.

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

3
RAdrian

Cela a fonctionné pour moi.

sous DBeaver 6.0: Allez dans Paramètres de connexion> Propriétés du pilote> Fuseau horaire du serveur> Définir l'heure UTC.

De plus, au printemps, la configuration de démarrage devait être définie sous la propriété.

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

3
Anil Gowda

Après avoir lu plusieurs articles sur ce sujet, testé différentes configurations et basé sur des informations tirées de ce fil de bugs mysql c'est ce que j'ai compris:

  • le fuseau horaire du serveur est important en particulier pour convertir les dates stockées dans la base de données vers le fuseau horaire du serveur d'applications. il y a d'autres implications, mais c'est la plus notable
  • Systèmes de fuseau horaire GMT x UTC. GMT a été conçu à la fin du 19ème siècle et peut être basculé entre l’heure normale et l’été. cette propriété peut conduire à une situation dans laquelle le serveur de base de données passe à l'heure d'été et que l'application ne le remarque pas (peut-être qu'il y a d'autres complications, mais je n'ai pas fait de recherche plus loin). UTC (basé au Portugal au lieu de GMT à Greenwich) ne varie pas dans le temps, donc plus stable
  • la définition de serverTimeZone a été introduite dans les versions 5.1 de mysql jdbc. jusqu'à la version 8, il pourrait être ignoré avec useLegacyDatetimeCode=true, ce qui, associé à useJDBCCompliantTimezoneShift=true, permettrait à l'application d'obtenir le fuseau horaire de la base de données à chaque connexion. Dans ce mode, les fuseaux horaires GMT tels que «Heure d'été britannique» seraient convertis au format Java/JDBC interne. De nouveaux fuseaux horaires peuvent être définis dans un fichier .properties tel que celui-ci
  • À partir de la version 8 du pilote jdbc, la correspondance temporelle automatique (useJDBCCompliantTimezoneShift) et le format d'heure hérité (useLegacyDatetimeCode) ont été supprimés ( voir mysql jdbc connector changelog ). Par conséquent, la définition de ces 2 paramètres est sans effet car ils sont complètement ignorés (la nouvelle valeur par défaut est useLegacyDateTimeCode=false)
  • De cette manière, le paramètre serverTimezone est devenu obligatoire si l'un des fuseaux horaires (serveurs d'applications/de bases de données) n'est pas au format "UTC + xx" ou "GMT + xx".
  • La définition de l'heure du serveur au format UTC n'a pas d'incidence (par exemple, avec jdbc:mysql://localhost:3306/myschema?serverTimezone=UTC, même si vos serveurs d'applications/de bases de données ne sont 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. mots, simplement configurer serverTimezone = UTC avec un fuseau horaire différent sur le serveur de base de données décalera 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 cet article StackOverflow )
  • Les bases de données configurées sur AWS (services Web Amazon) se voient attribuer automatiquement l'heure UTC + 0 par défaut ( voir la page d'aide AWS ici )
2
epol

La solution de @ Ingvar a fonctionné. 

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

Je suis en retard, mais si vous rencontrez les problèmes suivants 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

J'ai résolu ce problème sans aucun changement de code. allez simplement régler l’heure système et définir le fuseau horaire. Dans mon cas, le fuseau horaire par défaut était UTC et j'ai été remplacé par mon fuseau horaire local. Après avoir redémarré tous les services, tout a fonctionné pour moi. 

1
Nikunj Shroff

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

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

J'ai aussi essayé "& serverTimezone = MDT" et cela a échoué. Pour une raison quelconque, il n'aime pas l'heure avancée!

1
GordR

J'ai exécuté suivant sur mon côté base de données.

mysql> SET @@global.time_zone = '+00:00';

mysql> SET @@session.time_zone = '+00:00';

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

J'utilise la version du serveur: 8.0.17 - MySQL Community Server - GPL

source: https://community.Oracle.com/thread/4144569?start=0&tstart=

1
Vishrant

Dans mon cas, c’était un environnement de test et je devais faire en sorte qu’une application existante fonctionne sans modification de la configuration, et si possible sans modification de la configuration de MySQL. J'ai pu résoudre le problème en suivant les suggestions de @vinnyjames et en modifiant le fuseau horaire du serveur en UTC :

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

Cela me suffisait pour résoudre le problème.

0
Dmitriusan

D'accord avec la réponse @bluecollarcoder, mais il est préférable d'utiliserTimeZone.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 paramètre Timezone est mis à jour automatiquement en fonction du fuseau horaire de la machine locale.

0
Yerbol

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

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