web-dev-qa-db-fra.com

Type de données Oracle Date, transformé en 'YYYY-MM-DD HH24: MI: SS TMZ' via SQL

J'ai une application qui télécharge vers une colonne de type de données Oracle Data via:

TO_TIMESTAMP_TZ('2012-10-09 1:10:21 CST','YYYY-MM-DD HH24:MI:SS TZR')

Je dois maintenant extraire le format et le fuseau horaire suivants de cette colonne de données: "AAAA-MM-JJ HH24: MI: SS CDT"

Remarque: la date est téléchargée en CST mais doit être retournée en CDT.

J'ai Google mais n'ai trouvé que les types de données suivants:

SELECT dateColumn From dateTable;
09-NOV-12

SELECT TO_CHAR(dateColumn,'YYYY-MM-DD HH24:MI:SS') From dateTable;
2012-10-09 1:10:21

J'ai également essayé ce qui suit:

TO_TIMESTAMP_TZ(dateColumn,'YYYY-MM-DD HH24:MI:SS CDT')
data format not recognized

TO_TIMESTAMP_TZ(CRTE_DT,'YYYY-MM-DD HH24:MI:SS TZH:TZM')
09-NOV-12 1:10:21 AM +01:00
don't understand why this does not come back as YYYY-MM-DD?

Comment puis-je résoudre ce problème?

10
James Gallagher

Il y a un peu de confusion dans votre question:

  • un type de données Date n'enregistre pas le composant de fuseau horaire. Cette information est tronquée et perdue à jamais lorsque vous insérez un TIMESTAMP WITH TIME ZONE dans un Date.
  • Lorsque vous souhaitez afficher une date, soit à l'écran, soit pour l'envoyer vers un autre système via une API de caractères (XML, fichier ...), vous utilisez le TO_CHAR fonction. Dans Oracle, un Date n'a pas de format : c'est un point dans le temps.
  • Réciproquement, vous utiliseriez TO_TIMESTAMP_TZ pour convertir un VARCHAR2 en TIMESTAMP, mais cela ne convertira pas un Date en TIMESTAMP.
  • Tu utilises FROM_TZ pour ajouter les informations de fuseau horaire à un TIMESTAMP (ou un Date).
  • Dans Oracle, CST est un fuseau horaire mais CDT ne l'est pas. CDT est une information d'heure d'été.
  • Pour compliquer encore les choses, CST/CDT (-05:00) et CST/CST (-06:00) aura évidemment des valeurs différentes, mais le fuseau horaire CST héritera des informations d'heure d'été en fonction de la date par défaut.

Votre conversion n'est donc peut-être pas aussi simple qu'elle en a l'air.

En supposant que vous souhaitez convertir un Dated que vous savez être valide au fuseau horaire CST/CST à l'équivalent au fuseau horaire CST/CDT, vous utiliseriez:

SQL> SELECT from_tz(d, '-06:00') initial_ts,
  2         from_tz(d, '-06:00') at time zone ('-05:00') converted_ts
  3    FROM (SELECT cast(to_date('2012-10-09 01:10:21',
  4                              'yyyy-mm-dd hh24:mi:ss') as timestamp) d
  5            FROM dual);

INITIAL_TS                      CONVERTED_TS
------------------------------- -------------------------------
09/10/12 01:10:21,000000 -06:00 09/10/12 02:10:21,000000 -05:00

Mon format d'horodatage par défaut a été utilisé ici. Je peux spécifier un format explicitement:

SQL> SELECT to_char(from_tz(d, '-06:00'),'yyyy-mm-dd hh24:mi:ss TZR') initial_ts,
  2         to_char(from_tz(d, '-06:00') at time zone ('-05:00'),
  3                 'yyyy-mm-dd hh24:mi:ss TZR') converted_ts
  4    FROM (SELECT cast(to_date('2012-10-09 01:10:21',
  5                              'yyyy-mm-dd hh24:mi:ss') as timestamp) d
  6            FROM dual);

INITIAL_TS                      CONVERTED_TS
------------------------------- -------------------------------
2012-10-09 01:10:21 -06:00      2012-10-09 02:10:21 -05:00
20
Vincent Malgrat

pour convertir un TimestampTZ dans Oracle, vous faites

TO_TIMESTAMP_TZ('2012-10-09 1:10:21 CST','YYYY-MM-DD HH24:MI:SS TZR') 
  at time zone 'region'

voir ici: http://docs.Oracle.com/cd/E11882_01/server.112/e10729/ch4datetime.htm#NLSPG264

et ici pour les régions: http://docs.Oracle.com/cd/E11882_01/server.112/e10729/applocaledata.htm#NLSPG0141

par exemple:

SQL> select a, sys_extract_utc(a), a at time zone '-05:00' from (select TO_TIMESTAMP_TZ('2013-04-09 1:10:21 CST','YYYY-MM-DD HH24:MI:SS TZR') a from dual);

A
---------------------------------------------------------------------------
SYS_EXTRACT_UTC(A)
---------------------------------------------------------------------------
AATTIMEZONE'-05:00'
---------------------------------------------------------------------------
09-APR-13 01.10.21.000000000 CST
09-APR-13 06.10.21.000000000
09-APR-13 01.10.21.000000000 -05:00


SQL> select a, sys_extract_utc(a), a at time zone '-05:00' from (select TO_TIMESTAMP_TZ('2013-03-09 1:10:21 CST','YYYY-MM-DD HH24:MI:SS TZR') a from dual);

A
---------------------------------------------------------------------------
SYS_EXTRACT_UTC(A)
---------------------------------------------------------------------------
AATTIMEZONE'-05:00'
---------------------------------------------------------------------------
09-MAR-13 01.10.21.000000000 CST
09-MAR-13 07.10.21.000000000
09-MAR-13 02.10.21.000000000 -05:00

SQL> select a, sys_extract_utc(a), a at time zone 'America/Los_Angeles' from (select TO_TIMESTAMP_TZ('2013-04-09 1:10:21 CST','YYYY-MM-DD HH24:MI:SS TZR') a from dual);

A
---------------------------------------------------------------------------
SYS_EXTRACT_UTC(A)
---------------------------------------------------------------------------
AATTIMEZONE'AMERICA/LOS_ANGELES'
---------------------------------------------------------------------------
09-APR-13 01.10.21.000000000 CST
09-APR-13 06.10.21.000000000
08-APR-13 23.10.21.000000000 AMERICA/LOS_ANGELES
2
DazzaL