Även om det inte är uttryckligen specificerat för setTimestamp(int parameterIndex, Timestamp x)
drivrutiner måste följa reglerna som fastställts av setTimestamp(int parameterIndex, Timestamp x, Calendar cal)
javadoc:
Ställer in den angivna parametern till den givna
java.sql.Timestamp
värde, med den givnaCalendar
objekt. Drivrutinen använderCalendar
objekt för att konstruera en SQLTIMESTAMP
värde, som föraren sedan skickar till databasen. Med enCalendar
objekt kan föraren beräkna tidsstämpeln med hänsyn till en anpassad tidszon. Om ingenCalendar
objektet anges, använder drivrutinen standardtidszonen, som är den för den virtuella maskinen som kör programmet.
När du anropar med setTimestamp(int parameterIndex, Timestamp x)
JDBC-drivrutinen använder den virtuella maskinens tidszon för att beräkna datum och tid för tidsstämpeln i den tidszonen. Detta datum och tid är vad som lagras i databasen, och om databaskolumnen inte lagrar information om tidszonen går all information om zonen förlorad (vilket innebär att det är upp till applikationen/applikationerna som använder databasen att använda samma tidszon konsekvent eller kom på ett annat schema för att urskilja tidszon (dvs. lagra i en separat kolumn).
Till exempel:Din lokala tidszon är GMT+2. Du lagrar "2012-12-25 10:00:00 UTC". Det faktiska värdet som lagras i databasen är "2012-12-25 12:00:00". Du hämtar den igen:du får tillbaka den igen som "2012-12-25 10:00:00 UTC" (men bara om du hämtar den med getTimestamp(..)
), men när en annan applikation kommer åt databasen i tidszonen GMT+0, kommer den att hämta tidsstämpeln som "2012-12-25 12:00:00 UTC".
Om du vill lagra den i en annan tidszon, måste du använda setTimestamp(int parameterIndex, Timestamp x, Calendar cal)
med en Kalender-instans i den tidszon som krävs. Se bara till att du också använder motsvarande getter med samma tidszon när du hämtar värden (om du använder en TIMESTAMP
utan tidszonsinformation i din databas).
Så, förutsatt att du vill lagra den faktiska GMT-tidszonen, måste du använda:
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
stmt.setTimestamp(11, tsSchedStartTime, cal);
Med JDBC 4.2 bör en kompatibel drivrutin stödja java.time.LocalDateTime
(och java.time.LocalTime
) för TIMESTAMP
(och TIME
) genom get/set/updateObject
. java.time.Local*
klasser är utan tidszoner, så ingen konvertering behöver tillämpas (även om det kan öppna en ny uppsättning problem om din kod antog en specifik tidszon).