2016-11-28 3 views
1

В this answer следующий запрос предлагается:формат Oracle TO_DATE, символ «любой символ»

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

¿есть некоторый характер, которые будут использоваться в формате со значением «любой»? Я хотел заменить «CET» в форматной строке что-то вроде «...» или „###“, то есть:

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

Одним из примеров, ¿, какой формат будет принимать все следующие строки даты:

2017-12-31 
2017_12_31 
2017x12x31 

ответ

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

Вот еще один способ использования 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() немного более понятен, IMHO, что может только помочь в удобочитаемости и ремонтопригодности!).

С обновленной вопрос (который, кажется, больше вокруг даты части сепаратора, а не часовой пояс), следующий должен сделать трюк:

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 
+0

больше заинтересованы в общем случае, не ограничиваясь словом CET. В настоящее время это не обычный формат шаблона, который не позволяет использовать символ «any». Кто-то предложил «#», но мой тест отвергает его. –

+0

Шахта обобщена, правда? У меня есть две строки в подзапросе, которые предоставляют образцы данных для запроса для работы, один из которых - CET, другой PST. Запрос работает независимо. – Boneist

+0

К сожалению, я имею в виду, например, принять три строки, такие как «2017-12-01» или «2017_12_01» или «2017x12x01». Я добавлю разъяснение к вопросу. –

Смежные вопросы