2016-12-05 106 views
0

我有簡單的計算,我從日期減去間隔用時:與格式甲骨文TO_DATE不顯示時間

select TO_DATE('2016-12-05 23:04:59', 'YYYY-MM-DD HH24:MI:SS') - to_dsinterval('00 0:05:00') from dual; 

它工作正常,結果:2016年12月5日22點59分59秒

但它無法與時區正確工作,所以下一種方法解決了時區問題。我只是包裝用TO_DATE()一次

select TO_DATE(
TO_DATE('2016-12-05 23:04:59', 'YYYY-MM-DD HH24:MI:SS') - to_dsinterval('00 0:05:00')) from dual; 

表達,但現在事實證明時間爲零。結果應該是:2016年12月5日22時59分五十九秒但實際:2016年12月5日00:00:00

如果我添加格式外TO_DATE就象這樣:

select to_date(TO_DATE('2016-12-05 23:04:59', 'YYYY-MM-DD HH24:MI:SS') - to_dsinterval('00 0:05:00'), 'YYYY-MM-DD HH24:MI:SS') from dual; 

結果變得很奇怪:0005-12-16 00:00:00 我在做什麼錯了?

+1

減法的結果已經是日期。你不需要另一個'to_date()',這不能解決時區問題。如果你想在時區上進行一些操作,請使用'時區時間戳' – Kacper

回答

0

TO_DATE(char, fmt, nls)需要VARCHAR2參數。

執行TO_DATE('2016-12-05 23:04:59', 'YYYY-MM-DD HH24:MI:SS') - to_dsinterval('00 0:05:00')返回DATE的數據類型,當你把它傳遞給TO_DATE()甲骨文將其轉換爲VARCHAR2數據類型,因此參數的預期數據類型匹配(隱式調用TO_CHAR(value, NLS_DATE_FORMAT)執行這個轉換),然後轉化這個回數據類型爲DATE

你只需要做:

SELECT TO_DATE('2016-12-05 23:04:59', 'YYYY-MM-DD HH24:MI:SS') 
     - to_dsinterval('00 0:05:00') 
FROM DUAL; 

如果你要處理的時區,然後使用一個TIMESTAMP AT TIME ZONE,只是把它轉換到任何時區要存儲的日期爲:

SELECT TIMESTAMP '2016-12-05 23:04:59 Europe/Paris' AT TIME ZONE 'UTC' 
FROM DUAL; 

(將在巴黎時區創建您的時間戳並將其轉換爲UTC時區中的正確時間)。

0

DATE數據類型不支持任何時區功能,您必須使用TIMESTAMP WITH TIME ZONE

您的查詢

SELECT TO_DATE(TO_DATE('2016-12-05 23:04:59', 'YYYY-MM-DD HH24:MI:SS') - TO_DSINTERVAL('00 0:05:00'), 'YYYY-MM-DD HH24:MI:SS') 
FROM dual; 

做以下操作:

  1. 創建DATE '2016年12月5日23時04分59秒'
  2. 減去間隔00○時05分00' 秒
  3. 轉換爲VARCHAR2(使用NLS_DATE_FORMAT格式)
  4. 轉換爲使用YYYY-MM-DD HH24:MI:SS格式

如果您NLS_DATE_FORMAT將等於YYYY-MM-DD HH24:MI:SS這個查詢返回正確的輸出。

使用這一個:

SELECT TO_TIMESTAMP('2016-12-05 23:04:59', 'YYYY-MM-DD HH24:MI:SS') - TO_DSINTERVAL('00 0:05:00') 
FROM dual; 

TO_DATE(...工作爲好。如果您需要時區支持,您必須執行以下操作:

SELECT TO_TIMESTAMP_TZ('2016-12-05 23:04:59 Europe/Berlin', 'YYYY-MM-DD HH24:MI:SS TZR') - TO_DSINTERVAL('00 0:05:00') 
FROM dual; 
+0

'DATE'數據類型可以在它們上執行INTERVAL DAY TO SECOND算術。如果你做了'SELECT DUMP(TO_DATE('2016-12-05 23:04:59','YYYY-MM-DD HH24:MI:SS') - TO_DSINTERVAL('00 0:05:00'))FROM DUAL '返回'Typ = 13'這是'DATE'數據類型,所以不會隱式轉換爲'TIMESTAMP'。 – MT0

+0

你是對的,我糾正了我的答案。 –