Oracle
不同日期 Oracle 11g 與 TOAD
我有以下查詢:
SELECT to_date(to_char(to_date('01-FEB-1949'))) FROM DUAL; /*this returns 2/1/2049. */ SELECT to_date(to_char(to_date('01-FEB-1949'),'dd-MON-yyyy')) FROM DUAL; /*this returns 2/1/1949.*/
為什麼第一個返回年份
2049
而不是1949
?通過Google搜尋,我發現我可以通過更改
key
系統資料庫“強制”客戶日期格式成為一種願望:KEY_OraClient11g_home1 NLS_DATE_FORMAT : YYYY/MM/DD
提前致謝!
兩個函式都
TO_DATE
接受TO_CHAR
三個參數。最後兩個參數如果未指定,則採用預設值。第二個參數是格式。它將預設為您的
NLS_DATE_FORMAT
會話參數值。由於在轉換過程中您可能會失去資訊,因此沒有理由假設這兩個函式彼此相反。讓我們舉一個預設糟糕的格式選擇的例子
DD-MON-RR
:SQL> select to_date('01-FEB-1949', 'DD-MON-RR') d from dual; D ------------------------------ 01/02/1949 SQL> SELECT to_char(to_date('01-FEB-1949', 'DD-MON-RR'), 2 'DD-MON-RR') c 3 FROM dual; C ------------------------------ 01-FEB-49 SQL> SELECT to_date(to_char(to_date('01-FEB-1949', 'DD-MON-RR'), 2 'DD-MON-RR'), 3 'DD-MON-RR') d 4 FROM dual; D ----------- 01/02/2049
這表明我們在第二步中失去了數據:世紀失去了!第三步要彌補它,使用預設規則
RR
:
- 如果指定的兩位數年份是 00 到 49,則
+ 如果目前年份的後兩位數字是 00 到 49,則返回的年份與目前年份的前兩位數字相同。 + 如果目前年份的後兩位是 50 到 99,則返回年份的前 2 位比目前年份的前 2 位大 1。
- 如果指定的兩位數年份是 50 到 99,則
+ 如果目前年份的後兩位為 00 到 49,則返回年份的前 2 位比目前年份的前 2 位小 1。 + 如果目前年份的後兩位數字是 50 到 99,則返回的年份與目前年份的前兩位數字相同。
我們在第一種情況下,選擇的世紀是目前世紀(20XX)。
綜上所述:
- 不要依賴會話參數進行轉換,因為它們可以在您的控制之外更改,請使用顯式轉換規則。
- 不要使用
RR
orYY
格式,因為一年有 4 位數字(聽說過 Y2K 錯誤嗎?)- 當我們這樣做時,不要使用
MON
月份格式,如果有人使用另一個區域 NLS 設置,您的應用程序將無法工作:月份使用不同語言的不同縮寫!