Oracle TO_DATE格式,“任何字符”的符号

时间:2016-11-28 14:50:39

标签: oracle date parsing format

this answer中,建议使用以下查询:

SELECT TO_DATE(
         'Thu Nov 24 15:20:52 CET 2016',
         'DY MON DD HH24:MI:SS "CET" YYYY'
       )
FROM DUAL

¿有一些字符用于“any”的含义格式?我喜欢在格式字符串中用“......”或“###”替换“CET”,即:

'DY MON DD HH24:MI:SS ... YYYY'

一个例子,¿哪种格式将接受以下所有日期字符串:

2017-12-31
2017_12_31
2017x12x31

2 个答案:

答案 0 :(得分:1)

您可以通过正则表达式提取相关部分。

select 
TO_DATE(
      regexp_substr('Thu Nov 24 15:20:52 CET 2016', '^.+\d{2}:\d{2}:\d{2}')
    ||regexp_substr('Thu Nov 24 15:20:52 CET 2016', ' \d{4}$'), 
    'DY MON DD HH24:MI:SS YYYY')
from dual;

select 
TO_DATE(
   REGEXP_REPLACE('Thu Nov 24 15:20:52 CET 2016', '\w+ (\d{4})$', '\1'),
   'DY MON DD HH24:MI:SS YYYY')
from dual;

答案 1 :(得分:1)

这是使用to_timestamp_tz的另一种方式:

WITH sample_data AS (SELECT 'Thu Nov 24 15:20:52 CET 2016' str FROM dual UNION ALL
                     SELECT 'Fri Dec 11 23:16:39 PST 2015' str FROM dual)
SELECT str,
       to_timestamp_tz(str, 'Dy Mon dd hh24:mi:ss TZR yyyy', 'nls_date_language = english') timestamp_at_orig_tz,
       CAST(to_timestamp_tz(str, 'Dy Mon dd hh24:mi:ss TZR yyyy', 'nls_date_language = english') AS DATE) dt,
       CAST(to_timestamp_tz(str, 'Dy Mon dd hh24:mi:ss TZR yyyy', 'nls_date_language = english') AT TIME ZONE '-5:00' AS DATE) dt_at_utc_minus_5,
       cast(sys_extract_utc(to_timestamp_tz(str, 'Dy Mon dd hh24:mi:ss TZR yyyy', 'nls_date_language = english')) AS DATE) dt_at_utc
FROM   sample_data;

STR                          TIMESTAMP_AT_ORIG_TZ             DT                  DT_AT_UTC_MINUS_5   DT_AT_UTC
---------------------------- -------------------------------- ------------------- ------------------- -------------------
Thu Nov 24 15:20:52 CET 2016 24-NOV-16 15.20.52.000000000 CET 24/11/2016 15:20:52 24/11/2016 09:20:52 24/11/2016 14:20:52
Fri Dec 11 23:16:39 PST 2015 11-DEC-15 23.16.39.000000000 PST 11/12/2015 23:16:39 12/12/2015 02:16:39 12/12/2015 07:16:39

我给出了将时间戳作为字符串转换为日期的三种不同方法:

  1. 将时间戳转换为日期。请注意,这将丢失您拥有的任何时间戳信息 - 如果您真的不关心时区信息,则非常有用。
  2. 在将时间戳转换为日期之前,将时间戳转换为特定时区(在我的示例中为UTC - 5)。
  3. 在将时间戳转换为日期之前将时间戳转换为UTC(您可以使用上一个方法执行此操作,但sys_extract_utc()更加不言自明,恕我直言,这只会有助于提高可读性和可维护性!)。< / LI>

    使用您更新的问题(似乎更多地围绕日期部分分隔符,而不是时区),以下应该可以解决问题:

    WITH sample_data AS (SELECT '2017-12-31' dt_str FROM dual UNION ALL
                         SELECT '2017_12_31' dt_str FROM dual UNION ALL
                         SELECT '2017x12x31' dt_str FROM dual)
    SELECT dt_str,
           to_date(regexp_replace(dt_str,
                                  '([[:digit:]]{4}).([[:digit:]]{2}).([[:digit:]]{2})',
                                  '\1-\2-\3'), 'yyyy-mm-dd')
    FROM   sample_data;
    
    DT_STR     DT
    ---------- ----------
    2017-12-31 31/12/2017
    2017_12_31 31/12/2017
    2017x12x31 31/12/2017