TIMESTAMP WITH LOCAL TIME ZONE
fungerer sådan her:Når du skal arbejde med tidszoner i din applikation, så er en almindelig tilgang
Det er præcis sådan TIMESTAMP WITH LOCAL TIME ZONE
virker - den eneste forskel er
Af den grund kan du ikke ændre DBTIMEZONE
(med ALTER DATABASE SET TIME_ZONE='...';
) på din database længere, hvis databasen indeholder en tabel med et TIMESTAMP WITH LOCAL TIME ZONE
kolonne og kolonnen indeholder data.
SYSTIMESTAMP
returneres i tidszonen for databaseserverens operativsystem. DBTIMEZONE
er ikke tidszonen for SYSTIMESTAMP
eller SYSDATE
.
DBTIMEZONE
definerer det interne lagerformat for TIMESTAMP WITH LOCAL TIME ZONE
datatype kolonner. Glem dette, jeg kan ikke forestille mig nogen use-case, hvor du har brug for det.
Faktisk svarer din tabel til dette vælg:
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 laver CAST({time without time zone} with local time zone)
så prøver du at konvertere en dato/tidsværdi uden nogen tidszoneinformation til en dato/tidsværdi med tidszone. I princippet er dette ikke muligt, fordi Oracle mangler tidszoneinformationen, så Oracle antager en tidszone. Hvis du laver en sådan cast, betragter Oracle altid {tid uden tidszone} som angivet i SESSIONTIMEZONE
(i konverteringsøjeblikket).
Så CAST(sysdate AS timestamp(0) with local time zone)
svarer til
CAST(FROM_TZ(TO_TIMESTAMP(SYSDATE), SESSIONTIMEZONE) AS TIMESTAMP(0) WITH LOCAL TIME ZONE)`
hhv. 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)
For SYSDATE
dette er faktisk forkert, fordi SYSDATE
er angivet i tidszonen for databaseserverens operativsystem, ikke i SESSIONTIMEZONE. For den anden afhænger det af din hensigt, om resultatet er korrekt eller ej.
SYSTIMESTAMP
returnerer værdien TIMESTAMP WITH TIME ZONE
, den er altid uafhængig af din nuværende SESSIONTIMEZONE
. Men hvis du konverterer til TIMESTAMP WITH LOCAL TIME ZONE
det bliver selvfølgelig konverteret til din aktuelle lokale tidszone. Du kan også bruge CURRENT_TIMESTAMP
eller SYSTIMESTAMP AT LOCAL
som gør mere eller mindre det samme.
Denne kode
synes at være forkert. Resultatet skal være
-- 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
Forskellene ser ud, som de skal være, men de absolutte værdier ser ud til at være "falske" (eller der er et reelt problem med din database).