Oracle中的TIMESTAMP數據類型很多人用的都很少,所以即使最簡單的一個查詢返回的結果也會搞不清楚到底這個時間是什么時間點。
例如:
27-1月 -08 12.04.35.877000 上午
這個時間到底是幾點呢?中午12:04分,那就錯了,其實使用to_char函數轉換后得到如下結果:
2008-01-27 00:04:35:877000
說明這個時間是凌晨的00:04分,而不是中午的12:04分。
發生此問題的原因如下:
示例:
SELECT TO_CHAR(TO_DATE('2008-01-29 00:05:10', 'yyyy-mm-dd hh24:mi:ss'),'yyyy-mm-dd hh:mi:ss am') FROM DUAL
首先把一個00:05分的時間進行轉換,按照'yyyy-mm-dd hh:mi:ss am'格式進行轉換,得到的結果是:
2008-01-29 12:05:10 上午
這說明Oracle在進行日期轉換成字符串的過程中,如果小時轉換使用的是12進制的格式,則凌晨00點會被認為是上午12點,然后才是上午1點、 2點、3點。。。oracle中12進制的計時不是從0-11,而是從1-12的,所以如果是夜里零點,你不能記成1點,那只能記成12點了。(不知道這是不是跟洋人的習慣有關?)
現在我們來看一下Oracle中對TIMESTAMP的處理:
SELECT VALUE FROM NLS_SESSION_PARAMETERS WHERE PARAMETER = 'NLS_TIMESTAMP_FORMAT'
返回結果DD-MON-RR HH.MI.SSXFF AM,可以看到,這里默認情況下,使用的TIMESTAMP的格式是12進制的小時。
問題到這里已經找到根源了。
解決方法:
pl/sql developer中讀取的是注冊表中設置的NLS_TIMESTAMP_FORMAT格式,那么只要在注冊表中設置Oracle環境變量的地方(也就是設置ORACLE_HOME的地方)設置NLS_TIMESTAMP_FORMAT的格式(也就是創建這樣一個字符串項,然后設置它的值為你轉換需要的掩碼,我一般設置為YYYY-MM-DD HH24:MI:SS:FF6),然后關掉PL/SQL DEVELOPER,再繼續登陸,以后我們看到的TIMESTAMP時間就會自動轉換成大家需要的格式了。
如果格式想要顯示[07-APR-17 10.23.44.653941 AM]可以設置: