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