Не работайте с датами и временем как строками; Вы должны использовать соответствующие типы данных:
- Использовать тип данных
TIMESTAMP
для даты и времени с долями секунды. - Использовать тип данных
DATE
для даты ( и, если необходимо, обрежьте компонент времени до полуночи. - Используйте тип данных
INTERVAL
, если вы хотите время без даты.
Итак, вы можете использовать:
SELECT TRUNC( datetime ) AS "date",
datetime - TRUNC( datetime ) AS "time"
FROM (
SELECT TO_TIMESTAMP( original, 'DD-MON-RR HH12.MI.SS.FF6 AM' ) AS datetime
FROM table_name
)
Который выдаст (в зависимости от ваших настроек NLS):
date | time
:-------- | :----------------------------
21-JAN-16 | +000000000 13:20:51.097679000
02-FEB-16 | +000000000 13:32:53.469568000
01-DEC-15 | +000000000 06:00:41.315710000
14-JAN-16 | +000000000 16:11:53.107373000
21-JAN-16 | +000000000 13:05:15.113135000
03-FEB-16 | +000000000 12:06:10.128735000
04-FEB-16 | +000000000 18:24:59.557983000
Если вы действительно хотите использовать строки, преобразуйте строку в наиболее подходящую тип данных (TIMESTAMP
), а затем используйте TO_CHAR
, чтобы преобразовать его обратно в строку с моделью нужного формата:
SELECT TO_CHAR( datetime, 'DD-MON-YYYY' ) AS "date",
TO_CHAR( datetime, 'HH12.MI.SS AM' ) AS "time"
FROM (
SELECT TO_TIMESTAMP( original, 'DD-MON-RR HH12.MI.SS.FF6 AM' ) AS datetime
FROM table_name
)
, которая выводит:
date | time
:---------- | :----------
21-JAN-2016 | 01.20.51 PM
02-FEB-2016 | 01.32.53 PM
01-DEC-2015 | 06.00.41 AM
14-JAN-2016 | 04.11.53 PM
21-JAN-2016 | 01.05.15 PM
03-FEB-2016 | 12.06.10 PM
04-FEB-2016 | 06.24.59 PM
Чтобы ответить на вопрос, который вы задали:
Не знаете, где я ошибся?
У вас есть \.
перед окончательным значением меридиана, когда вы должны иметь пробел и выходной шаблон для времени должен быть \4:\5:\6 \8
:
SELECT REGEXP_REPLACE(
original,
'([[:digit:]]{2})\-([[:alpha:]]{3})\-([[:digit:]]{2})\ ([[:digit:]]{2})\.([[:digit:]]{2})\.([[:digit:]]{2})\.([[:digit:]]{1,} ([[:alpha:]]{2}))',
'\1-\2-20\3'
) "date",
REGEXP_REPLACE(
original,
'([[:digit:]]{2})\-([[:alpha:]]{3})\-([[:digit:]]{2})\ ([[:digit:]]{2})\.([[:digit:]]{2})\.([[:digit:]]{2})\.([[:digit:]]{1,} ([[:alpha:]]{2}))',
'\4:\5:\6 \8'
) "time"
FROM table_name
Выходы:
date | time
:---------- | :----------
21-JAN-2016 | 01:20:51 PM
02-FEB-2016 | 01:32:53 PM
01-DEC-2015 | 06:00:41 AM
14-JAN-2016 | 04:11:53 PM
21-JAN-2016 | 01:05:15 PM
03-FEB-2016 | 12:06:10 PM
04-FEB-2016 | 06:24:59 PM
* 10 47 * Вы можете упростить регулярное выражение, избавившись от ненужных escape-символов и используя группы символов perl в стиле, а не POSIX:
^(\d{2})-([A-Z]{3})-(\d{2}) (\d{2})\.(\d{2})\.(\d{2})\.(\d{1,}) ([AP]M)$
db <> fiddle здесь