Jordan, eigentlich hattest du die richtige Idee. Das Problem ist, dass es einen Fehler im MySQL-JDBC-Treiber gibt und das Kalenderargument standardmäßig vollständig ignoriert wird. Sehen Sie sich den Quellcode für PreparedStatement an, um wirklich zu sehen, was vor sich geht.
Beachten Sie, dass der Timestamp mit der Zeitzone der JVM formatiert wird. Dies funktioniert nur, wenn Ihre JVM die UTC-Zeitzone verwendet. Das Calendar-Objekt wird vollständig ignoriert.
this.tsdf = new SimpleDateFormat("''yyyy-MM-dd HH:mm:ss''", Locale.US);
timestampString = this.tsdf.format(x);
Damit MySQL das Calendar-Argument verwendet, müssen Sie den alten Datums-/Uhrzeitcode mit der folgenden Verbindungsoption deaktivieren:
useLegacyDatetimeCode=false
Sie können es also verwenden, wenn Sie sich wie folgt mit der Datenbank verbinden:
String url = "jdbc:mysql://localhost/tz?useLegacyDatetimeCode=false"
Wenn Sie den veralteten datetime-Code mithilfe der obigen Zeile deaktivieren, wird Ihr Zeitstempel in der Zeitzone des Zielkalenders gerendert:
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 ist ziemlich einfach zu sehen, was hier los ist. Wenn Sie ein Kalenderobjekt übergeben, wird dieses beim Formatieren der Daten verwendet. Andernfalls wird die Zeitzone der Datenbank zum Formatieren der Daten verwendet. Seltsamerweise wird, wenn Sie einen Kalender übergeben, auch die Zeit auf den angegebenen Timestamp-Wert gesetzt (was sinnlos zu sein scheint).