MySQL JDBC Driver 5.1.33 - Problema de zona horaria


361

Algunos antecedentes:

Tengo una aplicación web Java 1.6 que se ejecuta en Tomcat 7. La base de datos es MySQL 5.5. Anteriormente, estaba usando el controlador Mysql JDBC 5.1.23 para conectarme a la base de datos. Todo funcionó. Recientemente actualicé al controlador Mysql JDBC 5.1.33. Después de la actualización, Tomcat arrojaría este error al iniciar la aplicación.

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.

¿Por qué está pasando esto?


1
¿Cómo se ve tu URL JDBC?
David Levesque

Verifique mi respuesta stackoverflow.com/a/44720416/4592448 . Creo que es la mejor respuesta)
Fortran

Respuestas:


675

Aparentemente, para que la versión 5.1.33 del controlador JDBC de MySQL funcione con la zona horaria UTC, se debe especificar serverTimezoneexplícitamente en la cadena de conexión.

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

44
Según los documentos, useJDBCCompliantTimezoneShift no tiene ningún efecto cuando se usa useLegacyDatetimeCode = false. Por lo tanto, no es necesario allí ...
matof

24
Esto resuelve mi error. Nota adicional, escapar del & con & amp; en archivo 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

55
Eso no es correcto El punto de usoLegacyDatetimeCode = false no es tener que especificar serverTimezone para que el cliente corrija las diferencias de zona horaria. Es un error en esa versión del cliente MySQL.
antgar9

2
Esta solución arruina la zona horaria a excepción de GMT. Creo que la solución correcta está subestimada una a continuación
DuncanSungWKim

1
La solución funciona con 8.0.17. Sucedió con una nueva instalación de MySQL. No puedo creer que este error no se haya solucionado después de tantos años.
Tilman Hausherr

101

He resuelto este problema configurando MySQL.

SET GLOBAL time_zone = '+3:00';


66
si usted está utilizando MSK zona horaria es 3, entonces es posible utilizar folowing como una dirección db: jdbc:mysql://localhost/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Europe/Moscow. Parece que mysql-connector no comprende nombres cortos de zonas horarias.
babay

2
¿Qué haces cuando el horario de verano cambia el reloj?
isapir

3
Con mysql 8.0 puede llamar a "set persist time_zone = '+00: 00';" para configurarlo en UTC de manera persistente, sin necesidad de editar my.cnf o reiniciar el servidor. Ver mysqlserverteam.com/…
ccleve

Si está configurando esto mediante una consulta SQL manual única, esta configuración volverá a cuál era el valor original después de un reinicio de la base de datos.
CBA110

funciona: recuerde modificar su cadena de zona horaria local en lugar de +3 SET GLOBAL time_zone = '+3: 00';
Pravin

61

Después de leer varias publicaciones sobre este tema, probar diferentes configuraciones y basarme en algunas ideas de este hilo de errores de mysql, eso es lo que he entendido:

  • la zona horaria del servidor es importante en particular para convertir las fechas almacenadas en la base de datos a la zona horaria del servidor de aplicaciones. hay otras implicaciones pero esta es la más notable
  • Sistemas de zona horaria GMT x UTC. GMT fue concebido a fines del siglo XIX y se puede cambiar entre horario estándar y horario de verano. Esta propiedad podría conducir a una situación en la que el servidor de la base de datos cambia al horario de verano y la aplicación no lo nota (tal vez hay otras complicaciones, pero no investigé más). UTC no varía con el tiempo (siempre está dentro de aproximadamente 1 segundo del tiempo solar medio a 0 ° de longitud).
  • La definición de serverTimeZone se introdujo en las versiones 5.1 de los conectores jdbc de mysql. hasta la versión 8 podría ignorarse useLegacyDatetimeCode=true, lo que en conjunto con useJDBCCompliantTimezoneShift=truela aplicación haría que la zona horaria de la base de datos en cada conexión. En este modo, las zonas horarias GMT como 'British Summer Time' se convertirían al formato interno java / JDBC. Se pueden definir nuevas zonas horarias en un archivo .properties como este
  • A partir de la versión 8 del controlador jdbc, se eliminaron la coincidencia automática de tiempo ( useJDBCCompliantTimezoneShift) y el formato de tiempo heredado ( useLegacyDatetimeCode) ( consulte el registro de cambios del conector mysql jdbc ). por lo tanto, configurar estos 2 parámetros no tiene ningún efecto ya que se ignoran por completo (el nuevo valor predeterminado es useLegacyDateTimeCode=false)
  • De esta manera, la configuración se serverTimezonehizo obligatoria si alguna de las zonas horarias (servidores de aplicaciones / bases de datos) no están en el formato 'UTC + xx' o 'GMT + xx'
  • No hay impacto de establecer la hora del servidor como UTC (por ejemplo jdbc:mysql://localhost:3306/myschema?serverTimezone=UTC, incluso si sus servidores de aplicaciones / bases de datos no están en esta zona horaria. Lo importante es que la cadena de conexión de la aplicación + la base de datos se sincronice con la misma zona horaria. En otras palabras , simplemente configurar serverTimezone = UTC con una zona horaria diferente en el servidor de la base de datos cambiará las fechas extraídas de la base de datos
  • La zona horaria predeterminada de MySQL se puede establecer en UTC + 0 con los archivos my.ini o my.cnf (windows / linux respectivamente) agregando la línea default-time-zone='+00:00'(detalles en esta publicación de StackOverflow )
  • Las bases de datos configuradas en AWS (servicios web de Amazon) se asignan automáticamente al tiempo predeterminado UTC + 0 ( consulte la página de ayuda de AWS aquí )

1
Buena respuesta, gracias. Las diversas viñetas son todas útiles. Fui con la sugerencia de poner un archivo default-time-zone = '+00:00'homebrew /usr/local/etc/my.cnf. Parece que los espacios alrededor =son importantes, por lo que puede editar esa viñeta para incluirlos.
Mark Edington el

51

Si está utilizando Maven, puede configurar otra versión del conector MySQL (tuve el mismo error, así que cambié de 6.0.2 a 5.1.39) en pom.xml:

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

Como se informó en otras respuestas, este problema se ha solucionado en las versiones 6.0.3 o superiores, por lo que puede usar la versión actualizada:

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

Maven reconstruirá automáticamente su proyecto después de guardar el pom.xmlarchivo.


2
Para aquellos que descargaron mysql-connector-java / 6 -> simplemente descarguen, por ejemplo, mysql-connector-java / 5.1.20 y debería funcionar. ¡Gracias!
Combinar

66
Se debe evitar la degradación. Además, no está arreglado con 6.0.6still. mejor usar la solución anterior
phil294

estoy consiguiendo el mismo error incluso con la última jarra [-conector mysql-java-6.0.5.jar: 6.0.5]
user2478236

18
Tengo esto incluso en 8.0.12
Robert Niestroj

13
8.0.13 da el mismo error. 5.1.47 funciona para mí sin embargo.
localhost

36

La cadena de conexión debe establecerse así:

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

Si está definiendo la conexión en un xmlarchivo (por ejemplo persistence.xml, standalone-full.xml, etc ..), en lugar de &que puedes usar &amp;o usar un CDATAbloque.


1
Eso no es correcto El punto de usoLegacyDatetimeCode = false no es tener que especificar serverTimezone para que el cliente corrija las diferencias de zona horaria.
antgar9

Esto funcionó para mí al conectarme a MySQL 5.7 con phpStorm 2019.1.4.
moult86

29

Este es un error en mysql-connector-java de la versión 5.1.33 a 5.1.37. Lo he informado aquí: http://bugs.mysql.com/bug.php?id=79343

Editado: Esto se ha corregido desde mysql-connector-java 5.1.39

Fue un error tipográfico en la clase TimeUtil en el método loadTimeZoneMappings que genera un archivo NPE que localiza /com/mysql/jdbc/TimeZoneMapping.properties. Si observa el código, el archivo debe ubicarse dentro del cargador de clases TimeUtil, no TimeZone:

TimeUtil.class.getResourceAsStream(TIME_ZONE_MAPPINGS_RESOURCE);

El parámetro useLegacyDatetimeCode permite corregir la diferencia entre las zonas horarias del cliente y del servidor automáticamente cuando se usan fechas. Por lo tanto, le ayuda a no tener que especificar zonas horarias en cada parte. Aunque usar el parámetro serverTimeZone es una solución alternativa, y mientras se lanza el parche, puede intentar corregir el código usted mismo como lo hice yo.

  • Si se trata de una aplicación independiente, puede intentar simplemente agregar una clase com / mysql / jdbc / TimeUtil corregida a su código y tener cuidado con el orden de carga de jarras. Esto puede ayudar: https://owenou.com/2010/07/20/patching-with-class-shadowing-and-maven.html

  • Si se trata de una aplicación web, la solución más fácil es crear su propio mysql-connector-java-5.1.37-patched.jar, sustituyendo el .class directamente en el jar original.


Dulce, gracias por informar esto. Me alegra que alguien haya podido localizar el error. ¿Sabes cuándo se lanzará la solución?
bluecollarcoder

La solución que sugiere es excelente, pero creo que modificar la fuente del controlador y administrar la dependencia de Maven probablemente sea demasiado molesto para la mayoría de las personas.
bluecollarcoder

44
@Gili Esto no se corrigió a partir de la versión 6.0.6
Imme22009

66
El error todavía está presente en 8.0.11
John Little

3
@JohnLittle También tengo este problema en 8.0.15, pero ya no es causado por el error. Las zonas horarias se cargan correctamente, pero CET y CEST (estas zonas horarias me causan problemas) no se incluyen ni en TimeZone.getAvailableIDs()ni en, TimeZoneMapping.propertiespor lo que esta solución no ayudará aquí. Probablemente, la solución se establecería comoserverTimezone=Europe/Berlin
JPT

29

Resolví poner debajo de la cadena de conexión en la URL

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

1
Eso no es correcto El punto de usoLegacyDatetimeCode = false no es tener que especificar serverTimezone para que el cliente corrija las diferencias de zona horaria.
antgar9

25

Funcionó para mí simplemente agregando serverTimeZone = UTC en application.properties.
spring.datasource.url=jdbc:mysql://localhost/db?serverTimezone=UTC


22
  1. Agregué el archivo de configuración mysql en la sección [mysqld]

    default_time_zone='+03:00'
  2. Y reinicie el servidor mysql:

    sudo service mysql restart

Donde +03: 00 mi zona horaria UTC.

Ruta al archivo de configuración en mi os ubuntu 16.04:

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

ADVERTENCIA: SI SU ZONA HORARIA TIENE TIEMPO DE VERANO E INVIERNO. DEBE CAMBIAR UTC EN CONFIGURACIÓN SI CAMBIA HORA. DOS VECES EN EL AÑO (USUALMENTE) O FIJE LA CRONTAB CON SUDO.

Mi conexión urd jdbc:

"jdbc:mysql://localhost/java"

1
Tener que reiniciar Mysql es básicamente un no iniciador en casi todos los casos de uso de producción. Se convierte en un problema aún mayor cuando las réplicas están involucradas.
bluecollarcoder

@bluecollarcoder Requiere agregar solo en la sección [mysqld]. O agregue la sección [mysqld] si no tiene la sección. Ejemplo mi config pastebin.com/j4F7t2KS
Fortran

1
Actualicé el / etc / localtime de mi servidor Linux de / usr / share / zoneinfo / US / Pacific a / usr / share / zoneinfo / America / Los_Angeles y luego reinicié el servicio mysql y esto me solucionó el problema.
vinnyjames

En mi caso para la sintaxis proporcionada, hubo un error al reiniciar, y la sintaxis correcta fue: en su default-time-zone='+03:00'lugar, según esta respuesta . También viene de DBeaver.
wscourge

no s apropiado si usted tiene que decirle a cada desarrolladores en su empresa para alterar su configuración MySQL :)
pheromix

16

Tengo el mismo problema y lo resolví agregando solo "? ServerTimezone = UTC" a mi conexión de cadena.

# #

sinossi mi problema:

java.sql.SQLException: el valor de zona horaria del servidor 'CEST' no se reconoce o representa más de una zona horaria. Debe configurar el servidor o el controlador JDBC (a través de la propiedad de configuración serverTimezone) para usar un valor de zona horaria más específico si desea utilizar el soporte de zona horaria.

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

El programa anterior generará ese error de zona horaria.

Después de que su nombre de la base de datos hay que añadir lo siguiente: ?useTimezone=true&serverTimezone=UTC. Una vez que haya hecho su código funcionará bien.

La mejor de las suertes :)



13

Todo lo que necesitamos para solucionar el problema serverTimezone:

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

A mí también me pasó con la última versión 5.4.15. Pero solucionado con esto: agregar "? ServerTimezone =" + TimeZone.getDefault (). GetID () "justo al lado de su base de datos, resuelve los problemas.
Tes

10

Puede usar el conector MySQL en la dependencia Maven,

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

Luego necesita establecer los parámetros correctos en el application.propertiesarchivo,

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

Estoy usando mysql-connector-java-8.0.13 y tuve el mismo problema. Creé mi base de datos en la consola de línea de comando y resolví este problema usando la solución de @Dimitry Rud en la línea de comando:

SET GLOBAL time_zone = '-6:00';

No necesitaba reiniciar nada, establecer la hora e inmediatamente ejecutar mi código en eclipse, se conectó sin problemas.

Se supone que el error se corrige en una versión anterior, pero creo que recibí este error porque después de crear la base de datos en la consola, no configuré esto. No estoy usando workbench ni otra aplicación para administrar esto en lugar de la consola.


6

Desde mysql workbench ejecute las siguientes instrucciones sql:

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

con las siguientes instrucciones sql verifique si se establecieron los valores:

SELECCIONE @@ global.time_zone, @@ session.time_zone;


2
Esto funcionó para mí cuando apareció el error en cuestión al intentar establecer una conexión desde IntelliJ IDEA.
Faheem Hassan Zunjani

6

Esto funcionó para mí.

en DBeaver 6.0: Vaya a Configuración de conexión> Propiedades del controlador> Zona horaria del servidor> Establecer UTC.

Además, en la configuración de arranque de primavera, tenía que establecer la propiedad a continuación.

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


5

Aparentemente, para que la versión 5.1.33 del controlador JDBC de MySQL funcione con la zona horaria UTC, se debe especificar explícitamente la zona horaria del servidor en la cadena de conexión.

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

3

También estaba teniendo exactamente el mismo problema en LibreOffice Base. Así que acabo de especificar una 'zona horaria de horario de verano' que no es en la cadena de conexión.
** ingrese la descripción de la imagen aquí **

Lo intenté sin el "& serverTimezone = MST" pero eso también falló.

También probé "& serverTimezone = MDT" y eso falló, así que por alguna razón, ¡no le gusta el horario de verano!


3

Tuve el mismo problema cuando trato de trabajar con el proyecto de arranque de primavera en Windows.

La URL de la fuente de datos debe ser:

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


3

Ejecute la consulta a continuación a mysql DB para resolver el error

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

Obtuve un error similar al tuyo pero mi El valor de zona horaria del servidor es 'Afr. centrale Ouest ', así que hice estos pasos:

MyError (en 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....

Enfrenté este problema cuando actualicé mi servidor mysql a SQL Server 8.0 (MYSQL80).

La solución más simple a este problema es simplemente escribir el siguiente comando en su MYSQL Workbench:

  SET GLOBAL time_zone = '+1:00'

El valor después de la zona horaria será igual a GMT +/- Diferencia en su zona horaria. El ejemplo anterior es para el norte de África (GMT + 1: 00) / o para India (GMT + 5: 30). Resolverá el problema.

Ingrese el siguiente código en su Mysql Workbench y ejecute la consulta

[enlace fuente para pregunta / problema]

[enlace de origen para la respuesta]

[Captura de pantalla de la solución]


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

Esta es realmente la solución a este problema, pero no solo copie y pegue en su programa. Si solo lee la línea, encontrará 'resultado', ese es el nombre de mi base de datos, y tiene que escribir la suya.

Hay tres componentes de cadena, el primero es url, el segundo es nombre de usuario y el tercero es contraseña. En el párrafo anterior borramos, url. Los componentes de la segunda y tercera cadena como su nombre de usuario y contraseña deben cambiar en consecuencia.

Gracias


1

Resolví este problema sin ningún cambio de código único. solo vaya a la configuración de hora del sistema y configure la zona horaria. En mi caso, la zona horaria predeterminada era UTC, que cambié a mi zona horaria local. Después de reiniciar todos los servicios, todo funcionó para mí.


1

Llego tarde, pero si está luchando con el siguiente error y está usando datasource (javax.sql.DataSource):

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

Establezca la siguiente línea para deshacerse del error:

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

1

En mi caso, era un entorno de prueba y tenía que hacer que una aplicación existente funcionara sin ningún cambio de configuración, y si era posible sin ningún cambio de configuración de MySQL. Pude solucionar el problema siguiendo la sugerencia de @vinnyjames y cambiando la zona horaria del servidor a UTC :

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

Hacer eso fue suficiente para que resolviera el problema.


1

He agregado la siguiente línea a mi /etc/mysql/my.cnfarchivo:

default_time_zone='+00:00'

Reinició el servidor MySQL:

systemctl restart mysql

Y funciona como un encanto.


1

No hay impacto de establecer la hora del servidor como UTC (por ejemplo, con jdbc:mysql://localhost:3306/myschema?serverTimezone=UTC , incluso si sus servidores de aplicaciones / bases de datos no están en esta zona horaria. Lo importante es que la cadena de conexión de la aplicación + la base de datos se sincronice con la misma zona horaria).

En otras palabras, simplemente configurar serverTimezone=UTCcon una zona horaria diferente en el servidor de la base de datos cambiará las fechas extraídas de la base de datos


0

De acuerdo con la respuesta @bluecollarcoder, pero es mejor usarla TimeZone.getDefault().getID();al final de la cadena de conexión:

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

En este caso, el Timezoneparámetro se actualiza automáticamente según la zona horaria de la máquina local.


Eso no es correcto El punto de usoLegacyDatetimeCode = false no es tener que especificar serverTimezone para que el cliente corrija las diferencias de zona horaria.
antgar9

0

Simplemente modifique la cadena de conexión con el siguiente código en el archivo application.properties.


spring.datasource.url=jdbc:mysql://localhost:3301/Db?
   useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=
   false&serverTimezone=UTC
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.