useTimezone er en ældre løsning. MySQL-teamet omskrev setTimestamp/getTimestamp-koden ret for nylig, men den vil kun blive aktiveret, hvis du indstiller forbindelsesparameteren useLegacyDatetimeCode=false, og du bruger den seneste version af mysql JDBC-stikket. Så for eksempel:
String url =
"jdbc:mysql://localhost/mydb?useLegacyDatetimeCode=false
Hvis du downloader mysql-connector-kildekoden og ser på setTimestamp, er det meget nemt at se, hvad der sker:
Hvis brug af ældre dato-tidskode =false, kaldes newSetTimestampInternal(...). Så, hvis kalenderen, der sendes til newSetTimestampInternal, er NULL, formateres dit datoobjekt i databasens tidszone:
this.tsdf = new SimpleDateFormat("''yyyy-MM-dd HH:mm:ss", Locale.US);
this.tsdf.setTimeZone(this.connection.getServerTimezoneTZ());
timestampString = this.tsdf.format(x);
Det er meget vigtigt, at Kalender er null - så sørg for, at du bruger:
setTimestamp(int,Timestamp).
... NOT setTimestamp(int,Timestamp,Calendar).
Det burde være tydeligt nu, hvordan dette fungerer. Hvis du konstruerer en dato:5. januar 2011 kl. 03:00 i Amerika/Los_Angeles (eller hvilken tidszone du vil) ved at bruge java.util.Calendar og kalde setTimestamp(1, myDate), så tager det din dato, brug SimpleDateFormat for at formatere den i databasens tidszone . Så hvis din DB er i Amerika/New_York, vil den konstruere strengen '2011-01-05 6:00:00', der skal indsættes (da NY er foran LA med 3 timer).
For at hente datoen, brug getTimestamp(int) (uden kalenderen). Igen vil den bruge databasens tidszone til at bygge en dato.
Bemærk:Webserverens tidszone er fuldstændig irrelevant nu! Hvis du ikke indstiller useLegacyDatetimecode til false, bruges webserverens tidszone til formatering - hvilket tilføjer en masse forvirring.
Bemærk:
Det er muligt, at MySQL klager over, at serverens tidszone er tvetydig. For eksempel, hvis din database er indstillet til at bruge EST, kan der være flere mulige EST-tidszoner i Java, så du kan afklare dette for mysql-connector ved at fortælle den præcis, hvad databasens tidszone er:
String url =
"jdbc:mysql://localhost/mydb?useLegacyDatetimeCode=false&serverTimezone=America/New_York";
Du behøver kun at gøre dette, hvis den klager.