【问题标题】:Oracle Date datatype, transformed to 'YYYY-MM-DD HH24:MI:SS TMZ' through SQLOracle Date 数据类型,通过 SQL 转换为 'YYYY-MM-DD HH24:MI:SS TMZ'
【发布时间】:2023-03-19 14:25:02
【问题描述】:

我有一个应用程序通过以下方式上传到 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 格式返回。

我在 Google 上搜索过,但只找到以下日期数据类型:

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?

我该如何解决这个问题?

【问题讨论】:

    标签: sql oracle date select


    【解决方案1】:

    你的问题有点混乱:

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

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

    假设您想将您知道在CST/CST 时区有效的Date d 转换为在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
    

    【讨论】:

    • 非常感谢文森特的帖子。这正是我一直在寻找的 :) 我的 SQL 现在看起来如下所示,它可以帮助其他任何人: SELECT to_char( ( FROM_TZ( CAST(dateColumn AS TIMESTAMP), '-06:00' ) AT TIME ZONE '-05: 00' ) ,'yyyy-mm-dd hh24:mi:ss TZR' ) FROM dateTable;最后一个问题,是否可以将“-06:00”转换为 CDT?
    • 对于 '-05:00' -> 'CDT',我能够将 to_char 包装在 replace() 中。感谢您的所有帮助:)
    • 不是真的,CDT 不是时区:您将始终在夏季使用 CDT,在冬季使用 CST。例如,这会产生一个错误:SELECT to_timestamp_tz('2013-01-01 CST CDT', 'yyyy-mm-dd TZR TZD') FROM dual,但如果将 january 替换为 jun ,它就可以正常工作。因此,您不能真正将CST/CST 转换为CST/CDT,因为给定的日期不能两者兼有(冬季前的过渡时间除外,例如2013-11-03 01:00:00
    • 是的,一年中时间从 CST 更改为 CDT,但 CST 始终保持 UTC -6,CDT 始终保持 UTC -5。因此,如果应用程序始终将时间输入为 CST(无论何时输入全年),则该时间可以与应用于它的 UTC -6 和 UTC -5 相关联,给出 CDT 但从不提及 CST 或 CDT,因为两者都不支持在甲骨文中。
    • 你是个美男子,文森特。一件事-我在Netsuite中使用它,它在后端使用oracle(或其语法),而from_tz在日期上不起作用。它在转换为时间戳后工作。
    【解决方案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
    

    【讨论】:

    • 感谢您的帖子 DazzaL,虽然您的帖子中没有提及,但您提供的链接让我走上了 FROM_TZ 和 CAST 的道路,在文森特提供完整解决方案之前,我已经接近答案了。如果您对我正在寻找的内容感兴趣,请查看 Vincent 的帖子以获得完整的解决方案。再次感谢您,顺便说一句,我投票支持您;)
    猜你喜欢
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 2022-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-31
    相关资源
    最近更新 更多