TIMESTAMP WITH LOCAL TIME ZONE
funziona in questo modo:quando devi lavorare con i fusi orari nella tua applicazione, un approccio comune è
Ecco esattamente come TIMESTAMP WITH LOCAL TIME ZONE
funziona - l'unica differenza è
Per questo motivo non puoi modificare DBTIMEZONE
(con ALTER DATABASE SET TIME_ZONE='...';
) sul tuo database più se il database contiene una tabella con un TIMESTAMP WITH LOCAL TIME ZONE
colonna e la colonna contiene dati.
SYSTIMESTAMP
viene ripristinato nel fuso orario del sistema operativo del server di database. DBTIMEZONE
è non il fuso orario di SYSTIMESTAMP
o SYSDATE
.
DBTIMEZONE
definisce il formato di memoria interna di TIMESTAMP WITH LOCAL TIME ZONE
colonne del tipo di dati. Dimentica questo, non riesco a immaginare nessun caso d'uso in cui ne avresti bisogno.
In realtà la tua tabella è equivalente a questa selezione:
select
CAST(systimestamp AS timestamp(0) with local time zone) as SYSTIMESTAMP_COL,
CAST(sysdate AS timestamp(0) with local time zone) as SYSDATE_COL,
CAST(current_timestamp AS timestamp(0) with local time zone) as CURRENT_TIMESTAMP_COL,
CAST(timestamp '2017-03-15 19:02:00' AS timestamp(0) with local time zone) as DATE_COL
from dual;
Quando crei CAST({time without time zone} with local time zone)
quindi si tenta di convertire un valore di data/ora senza alcuna informazione sul fuso orario in un valore di data/ora con fuso orario. In linea di principio ciò non è possibile perché Oracle non dispone delle informazioni sul fuso orario, quindi Oracle presume un fuso orario. Se esegui tale cast, Oracle considera sempre {time without time zone} come indicato in SESSIONTIMEZONE
(nel momento della conversione).
Quindi CAST(sysdate AS timestamp(0) with local time zone)
è equivalente a
CAST(FROM_TZ(TO_TIMESTAMP(SYSDATE), SESSIONTIMEZONE) AS TIMESTAMP(0) WITH LOCAL TIME ZONE)`
risp. CAST(timestamp '2017-03-15 19:02:00' AS timestamp(0) with local time zone)
significa
CAST(FROM_TZ(TIMESTAMP '2017-03-15 19:02:00', SESSIONTIMEZONE) AS TIMESTAMP(0) WITH LOCAL TIME ZONE)
Per SYSDATE
questo è effettivamente sbagliato, perché SYSDATE
viene fornito nel fuso orario del sistema operativo del server di database non in SESSIONTIMEZONE. Per il secondo dipende dalla tua intenzione se il risultato è corretto o meno.
SYSTIMESTAMP
restituisce il valore TIMESTAMP WITH TIME ZONE
, è sempre indipendente dal tuo SESSIONTIMEZONE
corrente . Ma se converti in TIMESTAMP WITH LOCAL TIME ZONE
viene convertito nel tuo attuale fuso orario locale, ovviamente. Puoi anche usare CURRENT_TIMESTAMP
o SYSTIMESTAMP AT LOCAL
che fa più o meno lo stesso.
Questo codice
sembra essere sbagliato. Il risultato dovrebbe essere
-- SYSTIMESTAMP_COL 15/03/2017 16:01:14
-- SYSDATE_COL 15/03/2017 19:01:14
-- CURRENT_TIMESTAMP_COL 15/03/2017 16:01:14
-- DATE_COL 15/03/2017 19:02:00
Le differenze sembrano come dovrebbero essere ma i valori assoluti sembrano essere "falsi" (o c'è un vero problema con il tuo database).