Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Recuperando o campo UTC DATETIME do MySQL em Java quando o fuso horário do servidor não é UTC


Seu cliente getDate() código parece correto até onde vai. Eu acho que você também precisa obter o driver MySQL Connector/J JDBC para tratar as datas armazenadas na tabela como datas UTC, para evitar uma conversão espúria de fuso horário. Isso significa definir o fuso horário efetivo do servidor, além do fuso horário da sessão do cliente e do Calendário usado para JDBC getTimestamp chamadas como você está fazendo.

Dê uma olhada nos valores que você obteve em sua declaração com falha e em qual direção o erro está:
expected:<Thu Apr 16 11:30:30 BST 2015> but was:<Thu Apr 16 10:30:30 BST 2015>

O que você voltou foi 10:30 BST, que é 9:30 GMT. Isso é consistente com o banco de dados tratando esse 10:30 na tabela como um valor BST e convertendo-o falsamente em GMT para você, antes de analisá-lo como uma data GMT. Essa é a direção oposta de um valor GMT sendo convertido de forma espúria para BST.

Isso pode ser um problema específico do JDBC, porque o JDBC exige que os horários sejam convertidos para a zona local. (Onde a API C do MySQL não o faz, provavelmente porque os tipos de tempo clássicos do C não são sensíveis à zona como os Java são.) E ele precisa saber de qual zona está convertendo de , também. O TIMESTAMP do MySQL tipo é sempre armazenado como UTC. Mas isso não é declarado para o DATETIME modelo. Eu acho isso implica que o MySQL irá interpretar DATETIME valores de coluna como estando no fuso horário do servidor. Que você mencionou como sendo definido como BST, e isso é consistente com a direção do deslocamento mostrado em sua mensagem de erro de afirmação.

O time_zone A variável de sessão que você define está dizendo ao servidor MySQL qual é o fuso horário da sua máquina cliente, mas não afeta o que o servidor pensa que é seu próprio fuso horário. Isso pode ser substituído pelo serverTimezone Propriedade de conexão JDBC . Na sua conexão, defina o serverTimezone para UTC e certifique-se de que useLegacyDatetimeCode está fora. (E examine as outras propriedades relacionadas à zona, se isso não funcionar.) Veja se isso faz com que suas datas apareçam como UTC com os mesmos valores de campo de calendário que no banco de dados.

Esteja ciente de que isso mudará a interpretação de outros DATETIME valores em seu banco de dados:todos eles vão se parecer com datas UTC agora (no contexto de sua conexão JDBC). Se isso está correto vai depender de como eles foram preenchidos inicialmente. Embora o código do cliente tenha o comportamento que você deseja, não sei se esse sistema como um todo pode se comportar de forma totalmente consistente sem definir o fuso horário do servidor como UTC no nível do servidor. Basicamente, se ele não tiver sua zona definida como UTC, ele não está totalmente configurado para o comportamento que você deseja e você está se esquivando dele.