web-dev-qa-db-fra.com

Oracle SQL: conversion d'horodatage en UTC

J'ai une simple requête de sélection comme ci-dessous, mais j'ai remarqué que je reviens aux heures régionales. Comment puis-je convertir en UTC dans mon relevé sélectionné?

select myTimeStamp, MyName, MyBranch from tableA

Résultat: '27/03/2014 15:15:26 '' john ',' london '

J'ai essayé d'utiliser sys_extract_utc (myTimeStamp) mais j'ai l'erreur

commande SQL pas correctement terminé

La colonne myTimestamp est de type 'date'.

13
Fearghal
select cast(mytimestamp as timestamp) at time zone 'UTC', 
       MyName, 
       MyBranch 
from tableA

Parce que mytimestamp est en fait un date et non un horodatage, vous devez le caster. En faisant cela, Oracle suppose que les informations stockées dans mytimestamp sont dans le fuseau horaire du serveur - si ce n'est pas le cas, vous devez utiliser la solution de Madhawas.

17

En fonction du type, il existe quelques problèmes en ce qui concerne le fuseau horaire à partir duquel Oracle effectue la conversion, en fonction du type de données de myTimestamp.

horodatage avec fuseau horaire

It Just Works ™. a_horse_with_no_name a la bonne réponse ici.

horodatage avec fuseau horaire local

il est implicitement converti en horodatage avec fuseau horaire, puis It Just Works ™. Encore une fois, a_horse_with_no_name est ici.

horodatage

Bien qu'il soit également implicitement converti en horodatage avec fuseau horaire, le fuseau horaire qui est attribué par défaut est le session fuseau horaire de la session (- === -) (par opposition à la base de données fuseau horaire).

  • L'invocation explicite de ceci est myTimestamp at local.
  • Alternativement (et probablement mieux), vous pouvez faire comme Madhawas dit et utiliser la fonction from_tz Pour construire explicitement une valeur avec un fuseau horaire explicite autre que celui de votre session.

date

Essayer de faire l'une des choses ci-dessus pour date échouera comme vous l'avez décrit:

  • myTimestamp at time zone 'UTC'
    ORA-30084: type de données non valide pour le datetime primaire avec le modificateur de fuseau horaire

  • from_tz(myTimestamp, 'America/New_York')
    ORA-00932: types de données incohérents: TIMESTAMP attendu a obtenu DATE

La solution ici consiste à convertir la date en timestamp en premier:

select from_tz(cast(myTimestamp as timestamp), 'America/New_York') from tableA

Exemple de script

Le script suivant illustre le comportement. Notez que sur mon système, dbtimezone est US/Central et sessiontimezone est GMT-05: 00.

J'utilise également to_char Pour convertir la sortie car j'ai trouvé que certains outils modifieront l'horodatage du résultat de manière subtile, en particulier s'ils n'ont pas un bon support d'horodatage (c'est rare de nos jours, mais toujours potentiellement un problème) .

alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS'
/
alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS'
/
alter session set nls_timestamp_tz_format = 'YYYY-MM-DD HH24:MI:SS TZR'
/

select dbtimezone
      ,sessiontimezone
      ,to_char(timestamp '2017-01-01 06:00:00') as ts
      ,to_char(timestamp '2017-01-01 06:00:00' at local) as ts_at_local
      ,to_char(timestamp '2017-01-01 06:00:00' at time zone dbtimezone) as ts_at_db
      ,to_char(timestamp '2017-01-01 06:00:00' at time zone sessiontimezone) as ts_at_session
 from dual
/

La sortie sur mon système est la suivante (reformatée en colonne pour la lisibilité):

DBTIMEZONE          US/Central
SESSIONTIMEZONE     -05:00
TS                  2017-01-01 06:00:00
TS_AT_LOCAL         2017-01-01 06:00:00 -05:00
TS_AT_DB            2017-01-01 05:00:00 US/CENTRAL
TS_AT_SESSION       2017-01-01 06:00:00 -05:00
9
Chris R. Donnelly

Vous devez connaître votre fuseau horaire pour cela;

SELECT myTimeStamp, from_tz(myTimeStamp, 'America/New_York') AT TIME ZONE 'UTC' utc FROM dual;
5
Madhawas

À partir d'Oracle 19c, une nouvelle fonction est introduite qui est TO_UTC_TIMESTAMP_TZ

La fonction SQL TO_UTC_TIMESTAMP_TZ prend une chaîne de format de date ISO 8601 comme entrée varchar et renvoie une instance de type de données SQL TIMESTAMP WITH TIMEZONE. Il normalise l'entrée en temps UTC (temps universel coordonné, anciennement temps moyen de Greenwich). Contrairement à la fonction SQL TO_TIMESTAMP_TZ, la nouvelle fonction suppose que la chaîne d'entrée utilise le format de date ISO 8601, par défaut le fuseau horaire à UTC 0.

select TO_UTC_TIMESTAMP_TZ ( to_char(sysdate,'yyyy-mm-dd"T"HH:MI:SS') )  as utc 
   from dual;

 UTC
31-MAR-19 05.45.36.000000 AM +00:00
0
Kaushik Nayak