Oracle
 sql >> Base de données >  >> RDS >> Oracle

Horodatage Oracle avec traduction transparente des valeurs de fuseau horaire local

TIMESTAMP WITH LOCAL TIME ZONE fonctionne comme ceci :lorsque vous devez travailler avec des fuseaux horaires dans votre application, une approche courante est

C'est exactement comme ça TIMESTAMP WITH LOCAL TIME ZONE fonctionne - la seule différence est

Pour cette raison, vous ne pouvez pas modifier DBTIMEZONE (avec ALTER DATABASE SET TIME_ZONE='...'; ) sur votre base de données si la base de données contient une table avec un TIMESTAMP WITH LOCAL TIME ZONE colonne et la colonne contient des données.

SYSTIMESTAMP est renvoyé dans le fuseau horaire du système d'exploitation du serveur de base de données. DBTIMEZONE n'est pas le fuseau horaire de SYSTIMESTAMP ou SYSDATE .

DBTIMEZONE définit le format de stockage interne de TIMESTAMP WITH LOCAL TIME ZONE colonnes de type de données. Oubliez ça, je ne peux imaginer aucun cas d'utilisation où vous en auriez besoin.

En fait, votre table est équivalente à cette sélection :

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;

Lorsque vous faites CAST({time without time zone} with local time zone) puis vous essayez de convertir une valeur de date/heure sans aucune information de fuseau horaire en une valeur de date/heure avec fuseau horaire. En principe, cela n'est pas possible car Oracle n'a pas les informations de fuseau horaire, donc Oracle suppose un fuseau horaire. Si vous effectuez un tel cast, Oracle considère toujours {heure sans fuseau horaire} comme indiqué dans SESSIONTIMEZONE (au moment de la conversion).

Donc CAST(sysdate AS timestamp(0) with local time zone) est équivalent à

CAST(FROM_TZ(TO_TIMESTAMP(SYSDATE), SESSIONTIMEZONE) AS TIMESTAMP(0) WITH LOCAL TIME ZONE)` 

rép. CAST(timestamp '2017-03-15 19:02:00' AS timestamp(0) with local time zone) signifie

CAST(FROM_TZ(TIMESTAMP '2017-03-15 19:02:00', SESSIONTIMEZONE) AS TIMESTAMP(0) WITH LOCAL TIME ZONE)

Pour SYSDATE c'est en fait faux, car SYSDATE est donné dans le fuseau horaire du système d'exploitation du serveur de base de données et non dans SESSIONTIMEZONE. Pour le second, cela dépend de votre intention si le résultat est correct ou non.

SYSTIMESTAMP renvoie la valeur TIMESTAMP WITH TIME ZONE , il est toujours indépendant de votre SESSIONTIMEZONE actuel . Mais si vous convertissez en TIMESTAMP WITH LOCAL TIME ZONE il est bien sûr converti dans votre fuseau horaire local actuel. Vous pouvez également utiliser CURRENT_TIMESTAMP ou SYSTIMESTAMP AT LOCAL qui fait plus ou moins la même chose.

Ce code

semble avoir tort. Le résultat devrait être

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

Les différences semblent normales, mais les valeurs absolues semblent être "truquées" (ou il y a un vrai problème avec votre base de données).