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).