useTimezone är en äldre lösning. MySQL-teamet skrev om setTimestamp/getTimestamp-koden ganska nyligen, men den kommer bara att aktiveras om du ställer in anslutningsparametern useLegacyDatetimeCode=false och du använder den senaste versionen av mysql JDBC-anslutningen. Så till exempel:
String url =
"jdbc:mysql://localhost/mydb?useLegacyDatetimeCode=false
Om du laddar ner mysql-connector-källkoden och tittar på setTimestamp är det väldigt lätt att se vad som händer:
Om använd äldre datumkod =false, anropas newSetTimestampInternal(...). Sedan, om kalendern som skickas till newSetTimestampInternal är NULL, formateras ditt datumobjekt i databasens tidszon:
this.tsdf = new SimpleDateFormat("''yyyy-MM-dd HH:mm:ss", Locale.US);
this.tsdf.setTimeZone(this.connection.getServerTimezoneTZ());
timestampString = this.tsdf.format(x);
Det är mycket viktigt att Kalender är null - så se till att du använder:
setTimestamp(int,Timestamp).
... NOT setTimestamp(int,Timestamp,Calendar).
Det borde vara uppenbart nu hur detta fungerar. Om du konstruerar ett datum:5 januari 2011 03:00 i Amerika/Los_Angeles (eller vilken tidszon du vill) med java.util.Calendar och anropar setTimestamp(1, myDate), så kommer det att ta ditt datum, använd SimpleDateFormat för att formatera den i databasens tidszon . Så om din DB är i Amerika/New_York kommer den att konstruera strängen '2011-01-05 6:00:00' som ska infogas (eftersom NY ligger före LA med 3 timmar).
För att hämta datumet, använd getTimestamp(int) (utan kalendern). Återigen kommer den att använda databasens tidszon för att skapa ett datum.
Obs:Webserverns tidszon är helt irrelevant nu! Om du inte ställer in useLegacyDatetimecode till false, används webbserverns tidszon för formatering - vilket skapar mycket förvirring.
Obs:
Det är möjligt att MySQL klagar över att serverns tidszon är tvetydig. Till exempel, om din databas är inställd på att använda EST, kan det finnas flera möjliga EST-tidszoner i Java, så du kan förtydliga detta för mysql-connector genom att berätta exakt vad databasens tidszon är:
String url =
"jdbc:mysql://localhost/mydb?useLegacyDatetimeCode=false&serverTimezone=America/New_York";
Du behöver bara göra detta om den klagar.