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

Problemas de fuso horário Java MySQL Timestamp


Jordan, na verdade você teve a ideia certa. O problema é que há um bug no driver MySQL JDBC e o argumento Calendar é completamente ignorado por padrão. Veja o código-fonte de PreparedStatement para realmente ver o que está acontecendo.

Observe que o formato é o Timestamp usando o fuso horário da JVM. Isso só funcionará se sua JVM estiver usando o fuso horário UTC. O objeto Calendar é completamente ignorado.
this.tsdf = new SimpleDateFormat("''yyyy-MM-dd HH:mm:ss''", Locale.US);
timestampString = this.tsdf.format(x);

Para que o MySQL use o argumento Calendar, você deve desabilitar o código de data/hora legado com a seguinte opção de conexão:
useLegacyDatetimeCode=false

Então você pode usá-lo ao se conectar ao banco de dados assim:
String url = "jdbc:mysql://localhost/tz?useLegacyDatetimeCode=false"

Se você desabilitar o código de data e hora legado usando a linha acima, ele renderizará seu carimbo de data/hora no fuso horário do calendário de destino:
if (targetCalendar != null) {
    targetCalendar.setTime(x);
    this.tsdf.setTimeZone(targetCalendar.getTimeZone());

     timestampString = this.tsdf.format(x);
} else {
    this.tsdf.setTimeZone(this.connection.getServerTimezoneTZ());
    timestampString = this.tsdf.format(x);
}

É muito fácil ver o que está acontecendo aqui. Se você passar um objeto Calendar, ele o usará ao formatar os dados. Caso contrário, ele usará o fuso horário do banco de dados para formatar os dados. Estranhamente, se você passar um calendário, ele também definirá a hora para o valor de carimbo de data/hora fornecido (o que parece ser inútil).