Oracle
 sql >> Database >  >> RDS >> Oracle

java.sql.Timestamp è specifico per il fuso orario?

Sebbene non sia esplicitamente specificato per setTimestamp(int parameterIndex, Timestamp x) i conducenti devono seguire le regole stabilite da setTimestamp(int parameterIndex, Timestamp x, Calendar cal) javadoc:

Imposta il parametro designato sul java.sql.Timestamp specificato valore, utilizzando il Calendar specificato oggetto. Il driver utilizza il Calendar oggetto per costruire un TIMESTAMP SQL valore, che il driver invia quindi al database. Con un Calendar oggetto, il conducente può calcolare il timestamp tenendo conto di un fuso orario personalizzato. Se nessun Calendar oggetto è specificato, il driver utilizza il fuso orario predefinito, che è quello della macchina virtuale che esegue l'applicazione.

Quando chiami con setTimestamp(int parameterIndex, Timestamp x) il driver JDBC utilizza il fuso orario della macchina virtuale per calcolare la data e l'ora del timestamp in quel fuso orario. Questa data e ora è ciò che è memorizzato nel database e, se la colonna del database non memorizza le informazioni sul fuso orario, tutte le informazioni sulla zona andranno perse (il che significa che spetta alle applicazioni che utilizzano il database utilizzare il stesso fuso orario in modo coerente o inventare un altro schema per discernere il fuso orario (ad es. memorizzare in una colonna separata).

Ad esempio:il tuo fuso orario locale è GMT+2. Memorizzi "25-12-2012 10:00:00 UTC". Il valore effettivo memorizzato nel database è "2012-12-25 12:00:00". Lo recuperi di nuovo:lo ricevi di nuovo come "2012-12-25 10:00:00 UTC" (ma solo se lo recuperi usando getTimestamp(..) ), ma quando un'altra applicazione accede al database nel fuso orario GMT+0, recupererà il timestamp come "25-12-2012 12:00:00 UTC".

Se vuoi salvarlo in un fuso orario diverso, devi usare setTimestamp(int parameterIndex, Timestamp x, Calendar cal) con un'istanza di Calendar nel fuso orario richiesto. Assicurati solo di utilizzare anche il getter equivalente con lo stesso fuso orario durante il recupero dei valori (se usi un TIMESTAMP senza informazioni sul fuso orario nel database).

Quindi, supponendo che tu voglia memorizzare il fuso orario GMT effettivo, devi utilizzare:

Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
stmt.setTimestamp(11, tsSchedStartTime, cal);

Con JDBC 4.2 un driver compatibile dovrebbe supportare java.time.LocalDateTime (e java.time.LocalTime ) per TIMESTAMP (e TIME ) tramite get/set/updateObject . Il java.time.Local* le classi sono senza fuso orario, quindi non è necessario applicare alcuna conversione (sebbene ciò potrebbe aprire una nuova serie di problemi se il tuo codice presupponeva un fuso orario specifico).