sql >> Base de Datos >  >> RDS >> Mysql

Problemas de zona horaria de Java MySQL Timestamp

Jordan, en realidad tuviste la idea correcta. El problema es que hay un error en el controlador JDBC de MySQL y el argumento Calendario se ignora por completo de forma predeterminada. Mire el código fuente de PreparedStatement para ver realmente lo que está pasando.

Observe que el formato es la marca de tiempo usando la zona horaria de JVM. Esto solo funcionará si su JVM está utilizando la zona horaria UTC. El objeto Calendar se ignora por completo.

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

Para que MySQL use el argumento Calendario, debe deshabilitar el código de fecha/hora heredado con la siguiente opción de conexión:

useLegacyDatetimeCode=false

Así que podría usarlo cuando se conecte a la base de datos de esta manera:

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

Si deshabilita el código de fecha y hora heredado usando la línea anterior, su marca de tiempo aparecerá en la zona horaria del calendario 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);
}

Es bastante fácil ver lo que está pasando aquí. Si pasa un objeto Calendario, lo usará al formatear los datos. De lo contrario, utilizará la zona horaria de la base de datos para formatear los datos. Extrañamente, si pasa un calendario, también establecerá la hora en el valor de marca de tiempo dado (lo que parece no tener sentido).