首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Oracle 日期時間操作完全指南:函數、格式化、運算與效能實戰

     編輯:Oracle 資料庫相關知識

核心日期函數速查表

函數說明範例結果類型
SYSDATE資料庫伺服器當前日期時間SYSDATEDATE
SYSTIMESTAMP含時區、毫秒的當前時間SYSTIMESTAMPTIMESTAMP WITH TZ
CURRENT_DATESession 時區當前日期CURRENT_DATEDATE
CURRENT_TIMESTAMP(p)Session 時區當前時間戳,p=精度(0-9)CURRENT_TIMESTAMP(3)TIMESTAMP WITH TZ
LOCALTIMESTAMP(p)Session 時區當前時間戳 (無時區)LOCALTIMESTAMP(6)TIMESTAMP
DBTIMEZONE資料庫時區位移DBTIMEZONEVARCHAR2
SESSIONTIMEZONESession 時區位移SESSIONTIMEZONEVARCHAR2
ADD_MONTHS(d, n)日期加減 n 月ADD_MONTHS(SYSDATE, -3)DATE
MONTHS_BETWEEN(d1, d2)兩日期月差 (含小數)MONTHS_BETWEEN(d1,d2)NUMBER
LAST_DAY(d)該月最後一天LAST_DAY(SYSDATE)DATE
NEXT_DAY(d, weekday)日期 d 後第一個指定星期NEXT_DAY(SYSDATE,'FRIDAY')DATE
ROUND(d, fmt)日期捨入 (fmt: YEAR/MONTH/DD/DAY...)ROUND(SYSDATE,'MONTH')DATE
TRUNC(d, fmt)日期截斷TRUNC(SYSDATE,'YEAR')DATE
EXTRACT(field FROM d)擷取日期欄位EXTRACT(HOUR FROM SYSTIMESTAMP)NUMBER
NEW_TIME(d, tz1, tz2)舊版時區轉換 (已棄用)NEW_TIME(d,'GMT','PST')DATE
FROM_TZ(ts, tz)TIMESTAMP 加上時區FROM_TZ(ts,'Asia/Taipei')TIMESTAMP WITH TZ
TO_CHAR(d, fmt, nls)日期轉字串TO_CHAR(d,'YYYY-MM-DD HH24:MI:SS')VARCHAR2
TO_DATE(s, fmt, nls)字串轉日期TO_DATE('2023-01-01','YYYY-MM-DD')DATE
TO_TIMESTAMP(s, fmt)字串轉時間戳TO_TIMESTAMP('2023-01-01 12:00:00.123','YYYY-MM-DD HH24:MI:SS.FF')TIMESTAMP
CAST(x AS type)ANSI 標準型別轉換CAST(SYSDATE AS TIMESTAMP)目標類型

日期格式化元素完整表

元素說明範例
YYYY / YY / RRRR / RR年份 (RR 自動判斷世紀)2023 / 23
MM / MON / MONTH月份數字/縮寫/全名01 / JAN / JANUARY
DD / DDD月內/年內第幾天15 / 045
HH24 / HH / HH1224/12 小時制14 / 02
MI / SS / SSSSS分/秒/午夜至今秒數30 / 59 / 50400
FF / FF1..FF9毫秒/微秒/奈秒 (1-9 位).123456789
DAY / DY / D星期全名/縮寫/數字(1-7)MONDAY / MON / 2
AM / PM / A.M. / P.M.上午/下午標記PM
TZD / TZH / TZM / TZR時區縮寫/時差時/時差分/區域名CST / +08 / 00 / Asia/Taipei
IW / IYYYISO 週數/年份03 / 2023
W / WW月內/年內週數2 / 03
Q季度 (1-4)1
RM羅馬數字月份I
SP / SPTH拼寫數字/序數TWENTY-THREE / TWENTY-THIRD

間隔運算 (INTERVAL) - 10g+ 推薦

-- 年月間隔
SYSDATE - INTERVAL '2' YEAR
SYSDATE - INTERVAL '6' MONTH
SYSDATE - INTERVAL '2-6' YEAR TO MONTH

-- 日時分秒間隔
SYSDATE - INTERVAL '7' DAY
SYSDATE - INTERVAL '3' HOUR
SYSDATE - INTERVAL '30' MINUTE
SYSDATE - INTERVAL '45' SECOND
SYSDATE - INTERVAL '1 2:30:45' DAY TO SECOND

-- 運算
SYSDATE + INTERVAL '1' DAY - INTERVAL '2' HOUR
INTERVAL '2' HOUR * 3  -- 6 小時

常用實戰模式

1. 本月第一天/最後一天

TRUNC(SYSDATE, 'MM')           -- 本月 1 號 00:00:00
LAST_DAY(TRUNC(SYSDATE, 'MM')) -- 本月最後一天 00:00:00
LAST_DAY(SYSDATE) + 1 - 1/86400 -- 本月最後一天 23:59:59

2. 本年第一天/最後一天


TRUNC(SYSDATE, 'YYYY')
ADD_MONTHS(TRUNC(SYSDATE, 'YYYY'), 12) - 1/86400

3. 週一為週首日


TRUNC(SYSDATE, 'IW')  -- ISO 週首日 (週一)
NEXT_DAY(TRUNC(SYSDATE) - 7, 'MONDAY')  -- 相容舊版

4. 年齡/年資計算


-- 年齡 (滿歲)
FLOOR(MONTHS_BETWEEN(SYSDATE, birth_date) / 12)

-- 精確年月日
TRUNC(MONTHS_BETWEEN(SYSDATE, birth_date)/12) || '歲 ' ||
MOD(TRUNC(MONTHS_BETWEEN(SYSDATE, birth_date)), 12) || '月'

5. 毫秒/微秒精度


-- 當前毫秒
TO_CHAR(SYSTIMESTAMP, 'YYYY-MM-DD HH24:MI:SS.FF3')

-- 程式執行時間 (百萬分之一秒)
DECLARE
  l_start NUMBER := DBMS_UTILITY.GET_TIME;  -- 百分之一秒
BEGIN
  -- 待測程式碼
  DBMS_OUTPUT.PUT_LINE('耗時: ' || (DBMS_UTILITY.GET_TIME - l_start)/100 || ' 秒');
END;

6. 時區轉換最佳實踐


-- 正確方式:使用 TIMESTAMP WITH TIME ZONE
SELECT FROM_TZ(CAST(SYSDATE AS TIMESTAMP), 'UTC') AT TIME ZONE 'Asia/Taipei' 
FROM DUAL;

-- Session 時區影響
ALTER SESSION SET TIME_ZONE = 'Asia/Taipei';
SELECT CURRENT_TIMESTAMP FROM DUAL;  -- 顯示台灣時間

效能與最佳實踐

  1. 索引欄位勿加函數:WHERE TRUNC(dt) = TRUNC(SYSDATE) 導致全表掃描 → 改用 WHERE dt >= TRUNC(SYSDATE) AND dt < TRUNC(SYSDATE)+1
  2. 統一用 TIMESTAMP WITH TIME ZONE:跨時區系統避免時區混淆
  3. NLS 參數明確化:TO_CHAR(d, 'fmt', 'NLS_DATE_LANGUAGE=AMERICAN') 避免 Session 干擾
  4. 分區表按日期分區:大量歷史資料查詢效能大增
  5. 避免隱含轉換:WHERE date_col = '2023-01-01' → WHERE date_col = DATE '2023-01-01'

常見陷阱

陷阱錯誤寫法正確寫法
隱含字串轉日期WHERE d = '2023-01-01'WHERE d = DATE '2023-01-01'
索引失效WHERE TRUNC(d) = TRUNC(SYSDATE)WHERE d >= TRUNC(SYSDATE) AND d < TRUNC(SYSDATE)+1
月份加減邊界ADD_MONTHS('31-JAN-2023',1) → 28-FEB業務確認是否需調整為月底
時區混淆SYSDATE 跨時區比較統一用 SYSTIMESTAMP 或 CURRENT_TIMESTAMP
閏秒/夏令時間忽略 DST 變更用 TIMESTAMP WITH TIME ZONE + 時區資料庫
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved