TIMESTAMP WITH LOCAL TIME ZONE fungerar så här:När du ska arbeta med tidszoner i din applikation är ett vanligt tillvägagångssätt
Det är precis så TIMESTAMP WITH LOCAL TIME ZONE fungerar - den enda skillnaden är
Av den anledningen kan du inte ändra DBTIMEZONE (med ALTER DATABASE SET TIME_ZONE='...'; ) på din databas längre om databasen innehåller en tabell med en TIMESTAMP WITH LOCAL TIME ZONE kolumnen och kolumnen innehåller data.
SYSTIMESTAMP returneras i tidszonen för databasserverns operativsystem. DBTIMEZONE är inte tidszonen för SYSTIMESTAMP eller SYSDATE .
DBTIMEZONE definierar det interna lagringsformatet för TIMESTAMP WITH LOCAL TIME ZONE kolumner för datatyp. Glöm detta, jag kan inte föreställa mig något användningsfall där du skulle behöva det.
Egentligen motsvarar din tabell detta välj:
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;
När du gör CAST({time without time zone} with local time zone) sedan försöker du konvertera ett datum/tidsvärde utan tidszonsinformation till ett datum/tidsvärde med tidszon. I princip är detta inte möjligt eftersom Oracle saknar tidszonsinformation, så Oracle antar en tidszon. Om du gör en sådan cast anser Oracle alltid {tid utan tidszon} enligt SESSIONTIMEZONE (i omvandlingsögonblicket).
Alltså CAST(sysdate AS timestamp(0) with local time zone) motsvarar
CAST(FROM_TZ(TO_TIMESTAMP(SYSDATE), SESSIONTIMEZONE) AS TIMESTAMP(0) WITH LOCAL TIME ZONE)`
resp. CAST(timestamp '2017-03-15 19:02:00' AS timestamp(0) with local time zone) betyder
CAST(FROM_TZ(TIMESTAMP '2017-03-15 19:02:00', SESSIONTIMEZONE) AS TIMESTAMP(0) WITH LOCAL TIME ZONE)
För SYSDATE detta är faktiskt fel, eftersom SYSDATE ges i tidszonen för databasserverns operativsystem, inte i SESSIONTIMEZONE. För den andra beror det på din avsikt om resultatet är korrekt eller inte.
SYSTIMESTAMP returnerar värdet TIMESTAMP WITH TIME ZONE , den är alltid oberoende av din nuvarande SESSIONTIMEZONE . Men om du konverterar till TIMESTAMP WITH LOCAL TIME ZONE det konverteras till din nuvarande lokala tidszon, naturligtvis. Du kan också använda CURRENT_TIMESTAMP eller SYSTIMESTAMP AT LOCAL som gör mer eller mindre samma sak.
Denna kod
verkar vara fel. Resultatet bör vara
-- 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
Skillnaderna ser ut som de ska vara men de absoluta värdena verkar vara "förfalskade" (eller så finns det ett verkligt problem med din databas).