ジョーダン、実際あなたは正しい考えを持っていました。問題は、MySQL JDBCドライバーにバグがあり、Calendar引数がデフォルトで完全に無視されることです。 PreparedStatementのソースコードを見て、実際に何が起こっているかを確認してください。
JVMのタイムゾーンを使用したタイムスタンプの形式であることに注意してください。これは、JVMがUTCタイムゾーンを使用している場合にのみ機能します。 Calendarオブジェクトは完全に無視されます。
this.tsdf = new SimpleDateFormat("''yyyy-MM-dd HH:mm:ss''", Locale.US);
timestampString = this.tsdf.format(x);
MySQLがCalendar引数を使用するには、次の接続オプションを使用して従来の日付/時刻コードを無効にする必要があります。
useLegacyDatetimeCode=false
したがって、次のようにデータベースに接続するときに使用できます。
String url = "jdbc:mysql://localhost/tz?useLegacyDatetimeCode=false"
上記の行を使用して従来の日時コードを無効にすると、タイムスタンプがターゲットカレンダーのタイムゾーンでレンダリングされます:
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);
}
ここで何が起こっているかを確認するのは非常に簡単です。 Calendarオブジェクトを渡すと、データをフォーマットするときにこれが使用されます。それ以外の場合は、データベースのタイムゾーンを使用してデータをフォーマットします。不思議なことに、カレンダーを渡すと、時刻も指定されたタイムスタンプ値に設定されます(これは無意味に思えます)。