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?

bluecollarcoder
fonte
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
bluecollarcoder
fonte
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';

Dmitriy Rud
fonte
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 )
epol
fonte
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.

Gabriel Amazonas Mesquita
fonte
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.

Alireza Alallah
fonte
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.

antgar9
fonte
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
Rafael Costa Cavalcante
fonte
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

Ahmed AMMOURI
fonte
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"
Fortran
fonte
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 
felice de simone
fonte
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 :)

Aathil Ahamed
fonte
14

Eu executei a seguir no meu banco de dados.

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

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

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

Estou usando a versão Server: 8.0.17 - MySQL Community Server - GPL

fonte: https://community.oracle.com/thread/4144569?start=0&tstart=0

Vishrant
fonte
Você salvou meu tempo amigo. obrigado U.
Kumar
13

Tudo o que precisamos para resolver o problema serverTimezone:

String url = "jdbc:mysql://localhost:3306/db?serverTimezone=" + TimeZone.getDefault().getID()
Ingvar
fonte
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
Chaklader Asfak Arefe
fonte
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.

RAdrian
fonte
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;

toof06
fonte
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

Anil Gowda
fonte
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
harun ugur
fonte
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!

GordR
fonte
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

Berkay Ernalbant
fonte
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;
saurabh asthana
fonte
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]

iifast
fonte
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

Pratham Sarankar
fonte
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.

Nikunj Shroff
fonte
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");
Rituraj Singh Rathore
fonte
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.

Dmitriusan
fonte
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.

Tadej
fonte
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

Hermann N'ZI
fonte
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.

Yerbol
fonte
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
Mittal
fonte