2010-08-23 67 views
6

我需要的日期從該格式轉換:轉換一個XSD日期的xs:日期時間到Oracle日期

2002-10-10T12:00:00-05:00 (XS:日期時間定義在XML中)

Oracle日期。我已經習慣了在PL/SQL中使用它:to_date('date here','yyyymmdd'),有沒有辦法在保持時區信息的同時將其轉換?

謝謝

+0

@ user412045:你的問題不清楚。你想把這個'2002-10-10T12:00:00-05:00'轉換成這個'20021010'嗎? 「保持時區信息」是什麼意思? – 2010-08-23 15:52:53

+0

我想將2002-10-10T12:00:00-05:00轉換爲Oracle日期。 20021010只是一個例子。通過保持時區信息,我的意思是我希望能夠獲取完整的日期時間。謝謝 – MoreCoffee 2010-08-23 16:55:37

回答

7

Oracle日期沒有時區信息。您需要改爲使用TIMESTAMP數據類型。

它的工作原理是這樣的:

SQL> desc tz 
Name          Null? Type 
----------------------------------------- -------- ---------------------------- 
ID             NUMBER 
TS             TIMESTAMP(6) WITH TIME ZONE 
TNOW            TIMESTAMP(6) WITH TIME ZONE 

SQL> insert into tz 
    2 values (1 
    3   , to_timestamp_tz('2002-10-10 12:00:00-05:00' 
    4       , 'YYYY-MM-DD HH24:MI:SSTZH:TZM') 
    5   , systimestamp) 
    6/

1 row created. 

SQL> select * from tz 
    2/

     ID 
---------- 
TS 
--------------------------------------------------------------------------- 
TNOW 
--------------------------------------------------------------------------- 
     1 
10-OCT-02 12.00.00.000000 -05:00 
23-AUG-10 17.37.06.502000 +01:00 


SQL> 

注意,有牛逼在XSD符號棘手的問題。這拋出了一個ORA-01858異常,因爲它不是Oracle中的有效格式。我確定有一個解決方法,但它現在逃脫了我。


那麼,一個解決方法是應用SUBSTR()函數sto split打開時間戳的兩個部分,如Bob所示。但應該有更優雅的方式。


它可能沒有資格作爲「優雅」,但因爲它是一個字符串,我們可以用一個替代功能擺脫惱人的T:

SQL> insert into tz 
    2 values (2 
    3   , to_timestamp_tz(translate('2003-10-10T12:00:00-05:00', 'T', ' ') 
    4     , 'YYYY-MM-DD HH24:MI:SSTZH:TZM') 
    5   , systimestamp) 
    6/

1 row created. 

SQL> select * from tz 
    2/

     ID 
---------- 
TS 
--------------------------------------------------------------------------- 
TNOW 
--------------------------------------------------------------------------- 
     1 
10-OCT-02 12.00.00.000000 -05:00 
23-AUG-10 17.37.06.502000 +01:00 

     2 
10-OCT-03 12.00.00.000000 -05:00 
23-AUG-10 17.53.37.113000 +01:00 


SQL> 

但是考慮到所有的努力甲骨文有放入XMLDB,這是相當煩人的,沒有一個更加整潔的解決方案。


「我不明白你怎麼弄 -05:00」。

在我的原始示例中,我使用的格式掩碼爲'YYYY-MM-DD HH24:MI:SS-TZH:TZM'。這解釋了時區中的-作爲分隔符而不是的減號。因此它返回了+05:00。自從我更正了我的代碼示例以刪除最後一個破折號。現在時區正確呈現爲-05:00。對不起,有任何困惑。

+0

謝謝!但是當我執行 select to_timestamp_tz(translate('2003-10-10T12:00:00-05:00','T',''),'YYYY-MM-DD HH24:MI:SS-TZH:TZM ')從雙重; 我得到10-OCT-03 12.00.00.000000000 PM +05:00(我應該得到-05:00而不是+05:00)? – MoreCoffee 2010-08-23 17:11:43

+0

我不明白你是怎麼得到的-0.001.001 – MoreCoffee 2010-08-23 17:12:21

+0

完美,正是我需要的 – MoreCoffee 2010-08-23 17:20:23

2

下面是如何將其轉換爲DATE和TIMESTAMP WITH TIME ZONE數據類型的示例。請注意,日期類型時區信息丟失(從TIMESTAMP WITH TIME ZONE轉換):

declare 
    strDate  VARCHAR2(32767); 
    tzDate  TIMESTAMP WITH TIME ZONE; 
    dtDate  DATE; 
    nTimezone NUMBER; 
    dtDate_GMT DATE; 
begin 
    strDate := '2002-10-10T12:00:00-05:00'; 

    dtDate := TO_TIMESTAMP_TZ(SUBSTR(strDate, 1, 10) || 
          SUBSTR(strDate, 12, 8) || ' ' || 
          SUBSTR(strDate, 20, 6), 'YYYY-MM-DDHH:MI:SS TZH:TZM'); 
    tzDate := TO_TIMESTAMP_TZ(SUBSTR(strDate, 1, 10) || 
          SUBSTR(strDate, 12, 8) || ' ' || 
          SUBSTR(strDate, 20, 6), 'YYYY-MM-DDHH:MI:SS TZH:TZM'); 
    nTimezone := TO_NUMBER(SUBSTR(strDate, 20, 3)) + 
       (TO_NUMBER(SUBSTR(strDate, 24, 2))/60); 
    dtDate_GMT := dtDate - ((INTERVAL '1' HOUR) * nTimezone); 

    dbms_output.put_Line('dtDate=' || dtDate); 
    dbms_output.put_Line('dtDate=' || TO_CHAR(dtDate, 'YYYY-MM-DD HH24:MI:SS')); 
    dbms_output.put_line('tzDate=' || tzDate); 
    dbms_output.put_line('tzDate=' || TO_CHAR(tzDate, 'YYYY-MM-DD HH24:MI:SS TZH:TZM')); 
    dbms_output.put_line('nTimezone=' || nTimezone); 
    dbms_output.put_Line('dtDate_GMT=' || TO_CHAR(dtDate_GMT, 'YYYY-MM-DD HH24:MI:SS')); 
end; 

只是爲了好玩,我添加一些代碼的例子來拉時區超出字符串,然後將時區添加到本地時間以獲取GMT/UTC。

分享和享受。

9

一個簡短的回答:

SQL> select to_timestamp_tz('2002-10-10T12:00:00-05:00','yyyy-mm-dd"T"hh24:mi:sstzh:tzm') 
    2 from dual 
    3/

TO_TIMESTAMP_TZ('2002-10-10T12:00:00-05:00','YYYY-MM-DD"T"HH24:MI:SSTZH:TZM 
--------------------------------------------------------------------------- 
10-OCT-02 12.00.00.000000000 PM -05:00 

1 row selected. 

問候, 羅布。