13

我有一个应用程序通过以下方式上传到 Oracle 数据类型列:

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

我现在需要从此数据列中提取以下格式和时区:'YYYY-MM-DD HH24:MI:SS CDT'

注意:日期在 CST 中上传,但需要在 CDT 中返回。

我有谷歌,但只找到以下日期数据类型:

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

我也尝试了以下方法:

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?

我怎么解决这个问题?

4

2 回答 2

20

你的问题有点混乱:

  • 数据类型不Date保存时区组件。TIMESTAMP WITH TIME ZONE当您将 a插入a 时,这条信息将被截断并永远丢失Date
  • 当您想在屏幕上显示日期或通过字符 API(XML、文件...)将其发送到另一个系统时,您可以使用该TO_CHAR功能。在 Oracle 中,aDate没有格式:它是一个时间点。
  • 相反,您将使用TO_TIMESTAMP_TZ将 a 转换VARCHAR2为 a TIMESTAMP,但这不会将 a 转换Date为 a TIMESTAMP
  • 您用于FROM_TZ将时区信息添加到 a TIMESTAMP(或 a Date)。
  • 在 Oracle 中,CST是一个时区,但CDT不是。CDT是夏令时信息。
  • 更复杂的是,CST/CDT( -05:00) 和CST/CST( -06:00) 显然会有不同的值,但CST默认情况下,时区将根据日期继承夏令时信息。

因此,您的转换可能并不像看起来那么简单。

假设您想将Date d您知道在 time zone 有效的 a 转换为 time zoneCST/CST的等价物CST/CDT,您将使用:

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

这里使用了我的默认时间戳格式。我可以明确指定格式:

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
于 2013-04-05T13:09:26.607 回答
2

要在 oracle 中转换 TimestampTZ,您可以

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

见这里:http ://docs.oracle.com/cd/E11882_01/server.112/e10729/ch4datetime.htm#NLSPG264

这里是地区:http ://docs.oracle.com/cd/E11882_01/server.112/e10729/applocaledata.htm#NLSPG0141

例如:

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
于 2013-04-05T12:27:06.613 回答