Mysql
 sql >> Database >  >> RDS >> Mysql

Problemi con il fuso orario di Java MySQL Timestamp

Jordan, in realtà hai avuto l'idea giusta. Il problema è che c'è un bug nel driver MySQL JDBC e l'argomento Calendar è completamente ignorato per impostazione predefinita. Guarda il codice sorgente di PreparedStatement per vedere davvero cosa sta succedendo.

Si noti che il formato è il Timestamp che utilizza il fuso orario della JVM. Funzionerà solo se la tua JVM utilizza il fuso orario UTC. L'oggetto Calendario viene completamente ignorato.

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

Affinché MySQL utilizzi l'argomento Calendar, devi disabilitare il codice data/ora legacy con la seguente opzione di connessione:

useLegacyDatetimeCode=false

Quindi potresti usarlo quando ti connetti al database in questo modo:

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

Se disabiliti il ​​codice datetime legacy utilizzando la riga sopra, il timestamp verrà visualizzato nel fuso orario del calendario di destinazione:

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);
}

È abbastanza facile vedere cosa sta succedendo qui. Se passi un oggetto Calendar, lo utilizzerà durante la formattazione dei dati. In caso contrario, utilizzerà il fuso orario del database per formattare i dati. Stranamente, se passi un Calendario, imposterà anche l'ora sul valore di Timestamp (che sembra essere inutile).