Driver JDBC do MySQL 5.1.33 - Problema no fuso horário


360

Alguns antecedentes:

Eu tenho um webapp Java 1.6 em execução no Tomcat 7. O banco de dados é MySQL 5.5. Anteriormente, eu estava usando o driver Mysql JDBC 5.1.23 para conectar-se ao banco de dados. Tudo funcionou. Recentemente, atualizei para o driver Mysql JDBC 5.1.33. Após a atualização, o Tomcat lançaria esse erro ao iniciar o aplicativo.

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 que isso está acontecendo?


11
Como é o seu URL JDBC?
David Levesque 22/10

Verifique minha resposta stackoverflow.com/a/44720416/4592448 . Eu acho que é melhor resposta)
Fortran

Respostas:


674

Aparentemente, para que a versão 5.1.33 do driver JDBC do MySQL funcione com o fuso horário UTC, é necessário especificar o serverTimezoneexplicitamente na cadeia de conexão.

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

4
De acordo com os documentos, useJDBCCompliantTimezoneShift não tem efeito ao usar useLegacyDatetimeCode = false. Portanto, não é necessário lá ... #
275 matof

24
Isso resolve meu erro. Nota adicional, escape do & com & amp; no arquivo persistence.xml: <nome da propriedade = "javax.persistence.jdbc.url" value = "jdbc: mysql: // localhost / test? useUnicode = true & amp; useJDBCCompliantTimezoneShift = true & amp; useLegacyDatetimeCode = false & amp; serverTimezone = UTC"
Pdem

5
Isso não está correto. O ponto de useLegacyDatetimeCode = false não precisa especificar serverTimezone para que o cliente corrija as diferenças de fuso horário. É um bug nessa versão do cliente MySQL.
antgar9

2
Esta solução arruina o fuso horário, exceto o GMT. Eu acho que a solução certa é subestimada abaixo
DuncanSungWKim

11
solução funciona com 8.0.17. Aconteceu com uma nova instalação do MySQL. Não acredito que esse bug não foi corrigido depois de tantos anos.
Tilman Hausherr

101

Eu resolvi esse problema configurando o MySQL.

SET GLOBAL time_zone = '+3:00';


6
se você estiver usando MSK fuso horário é +3, então você pode usar folowing como um endereço db: jdbc:mysql://localhost/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Europe/Moscow. Parece que o mysql-connector não entende nomes curtos de fuso horário.
babay

2
O que você faz quando o horário de verão muda o relógio?
8408 Isapir is

3
Com o mysql 8.0 você pode chamar "set persist time_zone = '+00: 00';" para defini-lo como UTC persistentemente, sem a necessidade de editar my.cnf ou reiniciar o servidor. Veja mysqlserverteam.com/…
ccleve

Se você estiver definindo isso por meio de uma consulta SQL manual exclusiva, essa configuração será revertida para o valor original após a reinicialização do banco de dados.
CBA110 06/07/19

funciona - lembre-se de modificar sua seqüência de fuso horário local no lugar de +3 SET GLOBAL time_zone = '+3: 00';
Pravin

61

Depois de ler várias postagens sobre esse tópico, testando diferentes configurações e com base em algumas informações desse encadeamento de erros do mysql, é o que entendi:

  • o fuso horário do servidor é importante, em particular, para converter datas armazenadas no banco de dados no fuso horário do servidor de aplicativos. existem outras implicações, mas esta é a mais notável
  • Sistemas de fuso horário GMT x UTC. O GMT foi concebido no final do século XIX e pode ser alterado entre a hora padrão e a hora de verão. essa propriedade pode levar a uma situação em que o servidor de banco de dados muda para o horário de verão e o aplicativo não percebe (talvez haja outras complicações, mas não pesquisei mais). O UTC não varia ao longo do tempo (é sempre cerca de 1 segundo do tempo solar médio a 0 ° de longitude).
  • A definição serverTimeZone foi introduzida nos conectores mysql jdbc versões 5.1 à frente. até a versão 8, ela poderia ser ignorada useLegacyDatetimeCode=true, o que, em conjunto com useJDBCCompliantTimezoneShift=true, tornaria o aplicativo o fuso horário do banco de dados em todas as conexões. Nesse modo, os fusos horários GMT, como 'British Summer Time', seriam convertidos para o formato java / JDBC interno. Novos fusos horários podem ser definidos em um arquivo .properties como este
  • A partir da versão 8 do driver jdbc, a correspondência automática de horas ( useJDBCCompliantTimezoneShift) e o formato de hora herdado ( useLegacyDatetimeCode) foram removidos ( consulte o registro de alterações do mysql jdbc connector ). portanto, a definição desses 2 parâmetros não tem efeito, pois são completamente ignorados (o novo padrão é useLegacyDateTimeCode=false)
  • Dessa maneira, a configuração serverTimezonese torna obrigatória se qualquer um dos fusos horários (servidores de aplicativos / banco de dados) não estiver no formato 'UTC + xx' ou 'GMT + xx'
  • Não há impacto em definir a hora do servidor como UTC (por exemplo jdbc:mysql://localhost:3306/myschema?serverTimezone=UTC, mesmo que os servidores de aplicativos / banco de dados não estejam nesse fuso horário. O importante é que a cadeia de conexão do aplicativo + o banco de dados seja sincronizada com o mesmo fuso horário. Em outras palavras , basta definir serverTimezone = UTC com um fuso horário diferente no servidor do banco de dados, mudando as datas extraídas do banco de dados
  • O fuso horário padrão do MySQL pode ser definido como UTC + 0 com os arquivos my.ini ou my.cnf (windows / linux, respectivamente) adicionando a linha default-time-zone='+00:00'(detalhes nesta postagem do StackOverflow )
  • Os bancos de dados configurados na AWS (amazon web services) recebem automaticamente o horário padrão UTC + 0 ( consulte a página de ajuda da AWS aqui )

11
Boa resposta, obrigado. As várias balas são úteis. Fui com a sugestão de colocar um default-time-zone = '+00:00'no /usr/local/etc/my.cnfarquivo homebrew . Parece que os espaços ao redor do =são importantes, portanto, você pode editar esse marcador para incluí-los.
precisa saber é o seguinte

51

Se você estiver usando o Maven, poderá definir outra versão do conector MySQL (eu tive o mesmo erro, então mudei de 6.0.2 para 5.1.39) em pom.xml:

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

Conforme relatado em outras respostas, esse problema foi corrigido nas versões 6.0.3 ou superior, para que você possa usar a versão atualizada:

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

O Maven recriará automaticamente seu projeto depois que você salvar o pom.xmlarquivo.


2
Para quem baixou o mysql-connector-java / 6 -> basta fazer o download, por exemplo, mysql-connector-java / 5.1.20 e deve funcionar. Obrigado!
Combine

6
a desclassificação deve ser evitada. Além disso, não é corrigido com 6.0.6ainda. melhor usar a solução acima
phil294

Estou recebendo o mesmo erro, mesmo com o jar mais recente [mysql-connector-java-6.0.5.jar: 6.0.5]
user2478236

18
Eu tenho isso mesmo em 8.0.12
Robert Niestroj

13
8.0.13 dá o mesmo erro. 5.1.47 funciona para mim no entanto.
localhost

36

A cadeia de conexão deve ser definida assim:

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

Se você estiver definindo a conexão em um xmlarquivo (como persistence.xml, standalone-full.xml, etc ..), em vez de &você deve usar &amp;ou usar um CDATAbloco.


11
Isso não está correto. O ponto de useLegacyDatetimeCode = false não precisa especificar serverTimezone para que o cliente corrija as diferenças de fuso horário.
antgar9

Isso funcionou para eu me conectar ao MySQL 5.7 com o phpStorm 2019.1.4.
moult86

29

Este é um erro no mysql-connector-java da versão 5.1.33 a 5.1.37. Eu relatei aqui: http://bugs.mysql.com/bug.php?id=79343

Editado: Isso foi corrigido no mysql-connector-java 5.1.39

Foi um erro de digitação na classe TimeUtil no método loadTimeZoneMappings que gera um arquivo NPE localizando /com/mysql/jdbc/TimeZoneMapping.properties. Se você observar o código, o arquivo deverá estar localizado no carregador de classes TimeUtil, e não no TimeZone:

TimeUtil.class.getResourceAsStream(TIME_ZONE_MAPPINGS_RESOURCE);

O parâmetro useLegacyDatetimeCode permite corrigir a diferença entre os fusos horários do cliente e do servidor automaticamente ao usar datas. Por isso, ajuda você a não precisar especificar fusos horários em cada parte. Embora o parâmetro serverTimeZone seja uma solução alternativa e, enquanto o patch for lançado, você poderá tentar corrigir o código melhor sozinho, como eu fiz.

  • Se for um aplicativo independente, você pode simplesmente adicionar uma classe com / mysql / jdbc / TimeUtil corrigida ao seu código e ter cuidado com a ordem de carregamento do jar. Isso pode ajudar: https://owenou.com/2010/07/20/patching-with-class-shadowing-and-maven.html

  • Se for uma aplicação web, a solução mais fácil é criar seu próprio mysql-connector-java-5.1.37-patched.jar, substituindo o .class diretamente no jar original.


Doce, obrigado por relatar isso. Ainda bem que alguém foi capaz de identificar o bug. Você sabe quando a correção será lançada?
Bluecollarcoder

A solução que você está sugerindo é ótima, mas acho que modificar a fonte do driver e gerenciar a dependência do Maven provavelmente é muito chato para a maioria das pessoas.
Bluecollarcoder

4
@Gili Isso não foi corrigido no release 6.0.6
Imme22009 21/08

6
O bug ainda está presente em 8.0.11
John Little

3
@ JohnLittle Eu também tenho esse problema na 8.0.15, mas não é mais causado pelo bug. Os fusos horários são carregados corretamente, mas CET e CEST (esses fusos horários me causam problemas) não são incluídos nem no TimeZone.getAvailableIDs()nem no, TimeZoneMapping.propertiesportanto, esta solução não ajudará aqui. A solução provavelmente estaria definindo comoserverTimezone=Europe/Berlin
JPT

29

Resolvi colocar abaixo a string de conexão no URL

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

11
Isso não está correto. O ponto de useLegacyDatetimeCode = false não precisa especificar serverTimezone para que o cliente corrija as diferenças de fuso horário.
Antgar9

25

Funcionou para mim apenas adicionando serverTimeZone = UTC em application.properties.
spring.datasource.url=jdbc:mysql://localhost/db?serverTimezone=UTC


22
  1. Eu adicionei no arquivo de configuração do mysql na seção [mysqld]

    default_time_zone='+03:00'
  2. E reinicie o servidor mysql:

    sudo service mysql restart

Onde + 03: 00 meu fuso horário UTC.

Caminho para o arquivo de configuração no meu sistema operacional ubuntu 16.04:

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

AVISO: SE O SEU FUSO HORÁRIO TEM TEMPO DE VERÃO E INVERNO. VOCÊ DEVE MUDAR O UTC EM CONFIGURAR SE MUDAR DE HORA. DUAS VEZES NO ANO (geralmente) ou defina CRONTAB COM SUDO.

Minha conexão jdbc url:

"jdbc:mysql://localhost/java"

11
Ter que reiniciar o Mysql é basicamente um não iniciador em quase todos os casos de uso de produção. Isso se torna ainda mais problemático quando há replicações.
bluecollarcoder

@bluecollarcoder Requer adição apenas na seção [mysqld]. Ou adicione a seção [mysqld] se não a possui. Exemplo minha configuração pastebin.com/j4F7t2KS
Fortran

11
Atualizei o / etc / localtime do meu servidor Linux de / usr / share / zoneinfo / US / Pacific para / usr / share / zoneinfo / America / Los_Angeles, em seguida, reiniciei o serviço mysql e isso resolveu o problema.
vinnyjames 31/01

No meu caso, para a sintaxe fornecida, ocorreu um erro ao reiniciar e a sintaxe correta era: em default-time-zone='+03:00'vez disso, conforme esta resposta . Também vindo do DBeaver.
wscourge

não é apropriado se você tem que dizer a todos os desenvolvedores em sua empresa para alterar sua configuração MySQL :)
Pheromix

16

Eu tenho o mesmo problema e resolvi anexar apenas "? ServerTimezone = UTC" à minha conexão de string.

#

sinossi meu problema:

java.sql.SQLException: o valor do fuso horário do servidor 'CEST' não é reconhecido ou representa mais de um fuso horário. Você deve configurar o servidor ou o driver JDBC (por meio da propriedade de configuração serverTimezone) para usar um valor de fuso horário mais específico, se desejar utilizar o suporte ao fuso horário.

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

O programa acima irá gerar esse erro de fuso horário.

Após o seu nome do banco de dados que você tem que acrescentar o seguinte: ?useTimezone=true&serverTimezone=UTC. Depois de concluir, seu código funcionará bem.

Boa sorte :)



13

Tudo o que precisamos para resolver o problema serverTimezone:

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

Aconteceu comigo também com a versão 5.4.15 mais recente. Mas resolvido com isso: adicionar "? ServerTimezone =" + TimeZone.getDefault (). GetID () "ao lado do seu banco de dados, resolve os problemas.
Tes

10

Você pode usar o conector MySQL na dependência do Maven,

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

Então você precisa definir os parâmetros corretos no application.propertiesarquivo,

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

Estou usando o mysql-connector-java-8.0.13 e tive o mesmo problema. Criei meu banco de dados no console da linha de comando e resolvi esse problema usando a solução de @Dimitry Rud na linha de comando:

SET GLOBAL time_zone = '-6:00';

Não precisei reiniciar nada, definir o horário e executar imediatamente meu código no eclipse, ele estava conectado sem problemas.

O bug deve ser corrigido em uma versão mais antiga, mas acho que recebi esse erro porque, depois de criar o banco de dados no console, não o configurei. Não estou usando o ambiente de trabalho nem outro aplicativo para gerenciar isso, e não o console.


6

No mysql workbench, execute as seguintes instruções sql:

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

com as seguintes instruções sql, verifique se os valores foram definidos:

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


2
Isso funcionou para mim quando o erro em questão apareceu ao tentar fazer uma conexão com o IntelliJ IDEA.
Faheem Hassan Zunjani 08/04/19

6

Isso funcionou para mim.

no DBeaver 6.0: Vá para Configurações de conexão> Propriedades do driver> Fuso horário do servidor> Definir UTC.

Além disso, na configuração de inicialização da primavera, teve que definir a propriedade abaixo.

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


5

Aparentemente, para que a versão 5.1.33 do driver JDBC do MySQL funcione com o fuso horário UTC, é necessário especificar explicitamente o serverTimezone na cadeia de conexão.

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

3

Eu também estava tendo exatamente o mesmo problema no LibreOffice Base. Então, acabei de especificar um 'fuso horário de verão' na string de conexão.
** insira a descrição da imagem aqui **

Eu tentei sem o "& serverTimezone = MST", mas isso também falhou.

Eu também tentei "& serverTimezone = MDT" e isso falhou, então, por algum motivo, ele não gosta do horário de verão!


3

Eu tive o mesmo problema ao tentar trabalhar com o projeto de inicialização por mola no Windows.

O URL da fonte de dados deve ser:

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


3

Execute a consulta abaixo no banco de dados mysql para resolver o erro

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

Tenho um erro semelhante ao seu, mas o meu O valor do fuso horário do servidor é 'Afr. centrale Ouest ', então eu executei estas etapas:

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

Eu enfrentei esse problema quando atualizei meu servidor mysql para o SQL Server 8.0 (MYSQL80).

A solução mais simples para esse problema é simplesmente escrever o comando abaixo no seu MYSQL Workbench -

  SET GLOBAL time_zone = '+1:00'

O valor após o fuso horário será igual a GMT +/- Diferença no seu fuso horário. O exemplo acima é para o norte da África (GMT + 1: 00) / ou para a Índia (GMT + 5: 30). Isso resolverá o problema.

Digite o seguinte código no seu Mysql Workbench e execute o quesry

[link da fonte para a pergunta / problema]

[link da fonte para a resposta]

[Solução ScreenShot]


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

Esta é realmente a solução para esse problema, mas não copie e cole no seu programa. Se você acabou de ler a linha, encontrará 'resultout', esse é o nome do meu banco de dados e você deverá escrever o seu.

Existem três componentes de cadeia, o primeiro é o URL, o segundo é o nome de usuário e o terceiro é a senha. No parágrafo acima, limpamos, url. O segundo e o terceiro componentes String, como disse seu nome de usuário e senha, devem ser alterados de acordo.

obrigado


1

Resolvi esse problema sem nenhuma alteração de código único. basta ir para a configuração da hora do sistema e definir o fuso horário. No meu caso, o fuso horário padrão era UTC, que mudei para meu fuso horário local. Depois de reiniciar todos os serviços, tudo funcionou para mim.


1

Estou atrasado, mas se você estiver enfrentando o seguinte erro e usando a fonte de dados (javax.sql.DataSource):

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

Defina a seguinte linha para se livrar do erro:

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

1

No meu caso, era um ambiente de teste e eu tive que fazer um aplicativo existente funcionar sem nenhuma alteração na configuração e, se possível, sem nenhuma alteração na configuração do MySQL. Consegui corrigir o problema seguindo a sugestão @vinnyjames e alterando o fuso horário do servidor para UTC :

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

Fazer isso foi suficiente para eu resolver o problema.


1

Eu adicionei a seguinte linha ao meu /etc/mysql/my.cnfarquivo:

default_time_zone='+00:00'

Reiniciou o servidor MySQL:

systemctl restart mysql

E funciona como um encanto.


1

Não há impacto em definir a hora do servidor como UTC (por exemplo, com jdbc:mysql://localhost:3306/myschema?serverTimezone=UTC , mesmo que os servidores de aplicativos / banco de dados não estejam nesse fuso horário. O importante é que a cadeia de conexão do aplicativo + o banco de dados seja sincronizada com o mesmo fuso horário.

Em outras palavras, a simples configuração serverTimezone=UTCcom um fuso horário diferente no servidor de banco de dados mudará as datas extraídas do banco de dados


0

Concorde com a resposta @bluecollarcoder, mas é melhor usar TimeZone.getDefault().getID();no final da cadeia de conexão:

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

Nesse caso, o Timezoneparâmetro é atualizado automaticamente, dependendo do fuso horário da máquina local.


Isso não está correto. O ponto de useLegacyDatetimeCode = false não precisa especificar serverTimezone para que o cliente corrija as diferenças de fuso horário.
Antgar9

0

Apenas modifique a cadeia de conexão com o seguinte código no arquivo application.properties.


spring.datasource.url=jdbc:mysql://localhost:3301/Db?
   useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=
   false&serverTimezone=UTC
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.