Como alterar o fuso horário do mysql na conexão java

O Mysql é executado no GMT + 8, mas o tomcat é executado no GMT. quando salvar data e hora no database, parece executado ok, quando eu verificar o valor de data e hora no database, vejo o valor GMT. Mas quando eu tento obter o valor do database, o valor é alterado, parece que o valor no database é tomado como GMT + 8, então java alterar o valor para GMT.

Eu tento definir o link de url de conexão

useTimezone=true&serverTimezone=GMT 

mas não funciona

useTimezone é uma solução mais antiga. A equipe do MySQL reescreveu o código setTimestamp / getTimestamp muito recentemente, mas ele só será ativado se você definir o parâmetro de conexão useLegacyDatetimeCode = false e estiver usando a versão mais recente do conector JDBC do mysql. Então, por exemplo:

 String url = "jdbc:mysql://localhost/mydb?useLegacyDatetimeCode=false 

Se você baixar o código-fonte do conector mysql e olhar para setTimestamp, é muito fácil ver o que está acontecendo:

Se usar legado date time code = false, newSetTimestampInternal (…) será chamado. Em seguida, se o Calendário passado para newSetTimestampInternal for NULL, seu object de data será formatado no fuso horário do database:

 this.tsdf = new SimpleDateFormat("''yyyy-MM-dd HH:mm:ss", Locale.US); this.tsdf.setTimeZone(this.connection.getServerTimezoneTZ()); timestampString = this.tsdf.format(x); 

É muito importante que o Google Agenda seja null – portanto, verifique se você está usando:

 setTimestamp(int,Timestamp). 

… NÃO setTimestamp (int, Timestamp, Calendar).

Deve ser óbvio agora como isso funciona. Se você construir uma data: 5 de janeiro de 2011 às 3:00 em America / Los_Angeles (ou qualquer fuso horário que você quiser) usando java.util.Calendar e chamar setTimestamp (1, myDate), então ela pegará sua data, use SimpleDateFormat formatá-lo no fuso horário do database . Então, se o seu DB estiver na América / New_York, ele irá construir a String ‘2011-01-05 6:00:00’ a ser inserida (já que NY está à frente de LA por 3 horas).

Para recuperar a data, use getTimestamp (int) (sem o calendar). Mais uma vez, ele usará o fuso horário do database para criar uma data.

Nota: O fuso horário do servidor web é completamente irrelevante agora! Se você não definir o código useLegacyDatetim como false, o fuso horário do servidor da web será usado para formatação – adicionando muita confusão.


Nota:

É possível que o MySQL meu reclame que o fuso horário do servidor é ambíguo. Por exemplo, se seu database estiver configurado para usar o EST, pode haver vários fusos horários EST possíveis em Java, portanto, você pode esclarecer isso para o mysql-connector informando exatamente qual é o fuso horário do database:

 String url = "jdbc:mysql://localhost/mydb?useLegacyDatetimeCode=false&serverTimezone=America/New_York"; 

Você só precisa fazer isso se reclamar.