【问题标题】:Convert varchar into datetime in oracle在oracle中将varchar转换为日期时间
【发布时间】:2020-11-25 09:36:10
【问题描述】:

我的日期时间以“o”格式保存在数据库中。

例子:

2020-10-08T06:58:54.0000000+02:00

这种数据的合适格式是什么? 我想把它转换成日期时间。

【问题讨论】:

  • 你的列数据类型是VARCHAR吗?
  • 是的,它是一个 varchar 列
  • 转换数据时不要忽略时区。如果要将其转换为 DATE 数据类型(不支持时区),则还应将所有值转换为单个公共时区。

标签: sql string oracle datetime type-conversion


【解决方案1】:

修复您的数据模型!不要将日期存储为字符串;这是低效的(你需要将字符串转换为日期,只要你想执行artihmetic操作),并且不安全(你不能保证这些值是有效的日期)。

至于您的问题:这取决于您要将字符串转换为的数据类型。假设您想要timestamp with time zone,这似乎是这里最相关的选项(它允许小数秒和时区):

select to_timestamp_tz(
    '2020-10-08T06:58:54.0000000+02:00', 
    'yyyy-mm-dd"T"hh24:mi:ss.ff tzh:tzm'
) as myts
from dual

这会返回这个timestamp with time zone

08-OCT-20 06.58.54.000000000 +02:00

【讨论】:

    【解决方案2】:

    如果您希望这些日期-时间-时区值的比较仍然准确,请天真地将带有时区的日期时间值转换为日期时间并忽略时区。

    您的值有一个时区,因此存储数据最自然的方法是TIMESTAMP WITH TIME ZONE,您可以使用它进行转换:

    TO_TIMESTAMP_TZ( your_column, 'YYYY-MM-DD"T"HH24:MI:SS.FF7TZH:TZM' )
    

    但是,如果您希望将值作为 DATE 数据类型,则此数据类型不支持时区,您应该使用以下方法将所有值转换为公共时区(通常是 UTC 时区):

    CAST(
      TO_TIMESTAMP_TZ( your_column, 'YYYY-MM-DD"T"HH24:MI:SS.FF7TZH:TZM' )
      AT TIME ZONE 'UTC'
      AS DATE
    )
    

    如果你不使用公共时区,那么你会发现你可以比较值并得出错误的比较。

    例如:

    SELECT CASE
           WHEN TO_TIMESTAMP_TZ( '2020-10-08T06:58:54.0000000+00:00', 'YYYY-MM-DD"T"HH24:MI:SS.FF7TZH:TZM' )
                < TO_TIMESTAMP_TZ( '2020-10-08T07:58:54.0000000+02:00', 'YYYY-MM-DD"T"HH24:MI:SS.FF7TZH:TZM' )
           THEN 1
           ELSE 0
           END AS comparison
    FROM   DUAL
    

    SELECT CASE
           WHEN CAST(
                  TO_TIMESTAMP_TZ( '2020-10-08T06:58:54.0000000+00:00', 'YYYY-MM-DD"T"HH24:MI:SS.FF7TZH:TZM' )
                  AT TIME ZONE 'UTC'
                  AS DATE
                )
                < 
                CAST(
                  TO_TIMESTAMP_TZ( '2020-10-08T07:58:54.0000000+02:00', 'YYYY-MM-DD"T"HH24:MI:SS.FF7TZH:TZM' )
                  AT TIME ZONE 'UTC'
                  AS DATE
                )
           THEN 1
           ELSE 0
           END AS comparison
    FROM   DUAL
    

    两个输出:

    |比较 | | ---------: | | 0 |

    然而,天真地使用TO_DATE

    SELECT CASE
           WHEN TO_DATE( '2020-10-08T06:58:54.0000000+00:00', 'YYYY-MM-DD"T"HH24:MI:SS##############' )
                < TO_DATE( '2020-10-08T07:58:54.0000000+02:00', 'YYYY-MM-DD"T"HH24:MI:SS##############' )
           THEN 1
           ELSE 0
           END AS comparison
    FROM   DUAL
    

    输出:

    |比较 | | ---------: | | 1 |

    db小提琴here

    【讨论】:

      【解决方案3】:

      如果您的列是 varchar2 并且日期存储在字符串中,那么您可以使用 TO_DATE 将其转换为日期,如下所示:

      SQL> SELECT TO_DATE('2020-10-08T06:58:54.0000000+02:00', 'YYYY-MM-DD"T"HH24:MI:SS.#############')
        2    FROM DUAL;
      
      TO_DATE('2020-10-08T
      --------------------
      08-oct-2020 06:58:54
      
      SQL>
      

      # 用于跳过字符。我忽略了时区和毫秒部分,因为在转换为 Date(&Time) 时不需要它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-06-07
        • 1970-01-01
        • 2019-08-15
        • 2013-06-01
        • 2021-07-13
        • 2019-12-23
        • 2019-03-13
        相关资源
        最近更新 更多