sql >> Databasteknik >  >> RDS >> Oracle

Oracle tidsstämpel med lokala tidszonvärden transparent översättning

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



  1. Ställa in Identity på eller av i SQL-servern

  2. Jag behöver ovanliga mysql-resultat

  3. Postgresql datumformatfel

  4. Hur man tar bort många rader från ofta besökta tabeller