Oracle:将完整日期转换为不同的日期格式

时间:2016-07-28 13:11:28

标签: sql oracle date

在我的Oracle数据库中,我在表中有一个类型为VARCHAR2的列,其列表如下:

Wednesday, August 3, 2016 12:00:00 AM CEST

我希望将其转换为08-03-2016

之类的内容

我尝试使用TO_DATE后跟TO_CHAR但它失败了。一些指导会有所帮助。

3 个答案:

答案 0 :(得分:1)

一种解决方案是使用SUBSTR& INSTR

e.g:

SELECT TO_DATE(
 SUBSTR(SUBSTR(date_str,1,INSTR(date_str,',',-1)-1),INSTR(SUBSTR(date_str,1,INSTR(date_str,',',-1)-1) ,' ',-1))
  || SUBSTR(date_str,INSTR(date_str,',')+2,3)
  || SUBSTR(date_str,-21,4) ,'DDMONYYYY')
FROM
  ( SELECT 'Wednesday, August 23, 2016 12:00:00 AM CEST' AS date_str FROM dual )

或者

SELECT TO_DATE(SUBSTR(date_str,1, INSTR(date_str,',',-1)+5) ,'DAY, MONTH DD, YYYY') 
  FROM (
  SELECT 'Wednesday, August 3, 2016 12:00:00 AM CEST' AS date_str FROM dual
  )

答案 1 :(得分:1)

试试这个:

SELECT 
    TO_TIMESTAMP(
        REGEXP_SUBSTR('Wednesday, August 3, 2016 12:00:00 AM CEST', 
           '\w+ +\d+, \d{4} \d{2}:\d{2}:\d{2} (A|P)M'), 
        'fmMonth DD, fmYYYY HH:MI:SS AM') 
FROM dual;

RESP。

SELECT TO_CHAR(
    TO_TIMESTAMP(
        REGEXP_SUBSTR('Wednesday, August 3, 2016 12:00:00 AM CEST', 
           '\w+ +\d+, \d{4} \d{2}:\d{2}:\d{2} (A|P)M'), 
        'fmMonth DD, fmYYYY HH:MI:SS AM'), 
    'MM-DD-YYYY')
FROM dual;

如果您只需要一天但没有时间信息,那么您有好运,因为CEST含糊不清,请看:

SELECT TZABBREV, TZ_OFFSET(TZNAME), TZNAME
FROM V$TIMEZONE_NAMES
WHERE TZABBREV = 'CEST'
ORDER BY 2;

TZABBREV TZ_OFFSET(TZNAME)  TZNAME
======== ================== ============
CEST    +01:00  Africa/Algiers
CEST    +01:00  Europe/Lisbon
CEST    +01:00  Portugal
CEST    +02:00  Atlantic/Jan_Mayen
CEST    +02:00  CET
CEST    +02:00  Europe/Amsterdam
CEST    +02:00  Europe/Belgrade
CEST    +02:00  Europe/Berlin
CEST    +02:00  Europe/Bratislava
CEST    +02:00  Europe/Brussels
CEST    +02:00  Europe/Budapest
CEST    +02:00  Europe/Copenhagen
CEST    +02:00  Europe/Gibraltar
CEST    +02:00  Arctic/Longyearbyen
CEST    +02:00  Africa/Tunis
CEST    +02:00  Africa/Tripoli
CEST    +02:00  Africa/Ceuta
CEST    +02:00  Poland
CEST    +02:00  Libya
CEST    +02:00  Europe/Zurich
CEST    +02:00  Europe/Zagreb
CEST    +02:00  Europe/Warsaw
CEST    +02:00  Europe/Vienna
CEST    +02:00  Europe/Vatican
CEST    +02:00  Europe/Tirane
CEST    +02:00  Europe/Ljubljana
CEST    +02:00  Europe/Luxembourg
CEST    +02:00  Europe/Madrid
CEST    +02:00  Europe/Monaco
CEST    +02:00  Europe/Oslo
CEST    +02:00  Europe/Paris
CEST    +02:00  Europe/Podgorica
CEST    +02:00  Europe/Prague
CEST    +02:00  Europe/Rome
CEST    +02:00  Europe/San_Marino
CEST    +02:00  Europe/Sarajevo
CEST    +02:00  Europe/Skopje
CEST    +02:00  Europe/Stockholm
CEST    +03:00  Europe/Zaporozhye
CEST    +03:00  Europe/Tallinn
CEST    +03:00  Europe/Vilnius
CEST    +03:00  Europe/Minsk
CEST    +03:00  Europe/Kaliningrad
CEST    +03:00  Europe/Sofia
CEST    +03:00  Europe/Uzhgorod
CEST    +03:00  Europe/Athens
CEST    +03:00  Europe/Riga

因此,确定正确的时区并非易事。

答案 2 :(得分:0)

有一些单独的问题(除了在VARCHAR2列中存储带时区的时间戳,这开始是错误的。)

一个是CEST没有“预先安装”(至少在我的Oracle安装中没有; CEST无法识别)。您将不得不依赖于特定的时区文件。为了说明,我将使用EST(美国/东海岸)。

然后,您需要能够将字符串转换为带有时区的时间戳。你可以这样做:

select to_timestamp_tz('Thursday, July 28, 2016 09:16:15 AM EST',
                        'Day, Month dd, yyyy, hh:mi:ss AM tzr') as ts from dual;



TS
---------------------------------------
28-JUL-16 09.16.15.000000000 AM EST

此时,TS是时间戳;屏幕上显示的内容由我的会话的NLS_TIMESTAMP_TZ_FORMAT参数决定。顺便说一下,这假定您的NLS_LANGUAGE设置为'American',否则'Thursday'的转换将无效;您需要将nls_param参数添加到to_timestamp_tz()

然后,如果您需要将结果显示为'07-28-2016',则可以将整个怪物包裹在to_char(..., 'mm-dd-yyyy')内。

select to_char(to_timestamp_tz('Thursday, July 28, 2016 09:16:15 AM EST',
                  'Day, Month dd, yyyy, hh:mi:ss AM tzr'), 'mm-dd-yyyy') as ts from dual;



TS
----------
07-28-2016