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

Oracle 日期時間函數大全:27 個核心函數、格式模型、時區、閏年、分頁、脫敏實戰速查

     編輯:Oracle 資料庫相關知識

核心函數分類速查表

類別函數語法返回典型用途
獲取/構造SYSDATESYSDATEDATE資料庫服務器當前日期時間
SYSTIMESTAMPSYSTIMESTAMPTIMESTAMP WITH TIME ZONE高精度+時區
CURRENT_DATECURRENT_DATEDATE會話時區當前日期
CURRENT_TIMESTAMPCURRENT_TIMESTAMPTIMESTAMP WITH TIME ZONE會話時區高精度
LOCALTIMESTAMPLOCALTIMESTAMPTIMESTAMP會話時區無時區戳
DBTIMEZONEDBTIMEZONEVARCHAR2資料庫時區偏移
SESSIONTIMEZONESESSIONTIMEZONEVARCHAR2會話時區偏移
TO_DATETO_DATE(str, fmt)DATE字符串轉日期
運算/偏移ADD_MONTHSADD_MONTHS(d, n)DATE月份加減(自動處理月末)
LAST_DAYLAST_DAY(d)DATE所在月最後一天
NEXT_DAYNEXT_DAY(d, 'FRIDAY')DATE下一個指定週幾
MONTHS_BETWEENMONTHS_BETWEEN(d1, d2)NUMBER月份差(含小數)
NEW_TIMENEW_TIME(d, 'GMT', 'EST')DATE跨時區轉換(舊函數)
ROUNDROUND(d, 'MM')DATE四捨五入到月/年/日
TRUNCTRUNC(d, 'MM')DATE截斷到月/年/日首
GREATEST/LEASTGREATEST(d1, d2...)DATE最大/最小日期
格式化/轉換TO_CHARTO_CHAR(d, fmt)VARCHAR2日期轉字符串(報表核心)
TO_TIMESTAMPTO_TIMESTAMP(str, fmt)TIMESTAMP字符串轉時間戳
CASTCAST(d AS TIMESTAMP)TIMESTAMP類型轉換
EXTRACTEXTRACT(YEAR FROM d)NUMBER提取年/月/日/時/分/秒
間隔運算NUMTODSINTERVALNUMTODSINTERVAL(n, 'DAY')INTERVAL DAY TO SECOND數值轉日間隔
NUMTOYMINTERVALNUMTOYMINTERVAL(n, 'MONTH')INTERVAL YEAR TO MONTH數值轉年月間隔
+ / -d + 1.5, d - INTERVAL '1' DAYDATE/TIMESTAMP日期算術

格式模型元素速查(TO_CHAR/TO_DATE 通用)

元素含義範例
YYYY / RRRR4 位年份(RRRR 兩位年份自動推斷世紀)2024 / 24→2024
MM / MON / MONTH月份 數字/縮寫/全拼05 / MAY / MAY
DD / DDD月內天 / 年內天17 / 138
HH24 / HH1224/12 小時制14 / 02
MI / SS / FFn分/秒/毫微秒(n 位)30 / 45 / .123456
DAY / DY / D星期全拼/縮寫/數字(1-7)FRIDAY / FRI / 6
AM / PM / A.M.上午/下午標記PM
TZH / TZM / TZR時區時/分/區域名+08 / 00 / Asia/Shanghai

實戰組合拳範例

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


TRUNC(SYSDATE, 'MM')                    -- 本月 1 號 00:00
LAST_DAY(TRUNC(SYSDATE)) + 1 - 1/86400  -- 本月最後一天 23:59:59 (舊寫法)
TRUNC(ADD_MONTHS(SYSDATE, 1), 'MM') - 1/86400  -- 更優雅

2. 精確天數差(含時分秒)


-- 兩個 DATE 相減 = 天數 (含小數)
SELECT (SYSDATE - TO_DATE('2024-01-01','YYYY-MM-DD')) AS days_diff FROM dual;

-- 僅整天
SELECT FLOOR(SYSDATE - TO_DATE('2024-01-01','YYYY-MM-DD')) FROM dual;

3. 年齡計算(精確到年月日)


SELECT
    FLOOR(MONTHS_BETWEEN(SYSDATE, birth_dt)/12) AS years,
    MOD(FLOOR(MONTHS_BETWEEN(SYSDATE, birth_dt)), 12) AS months,
    TRUNC(SYSDATE - ADD_MONTHS(birth_dt,
        FLOOR(MONTHS_BETWEEN(SYSDATE, birth_dt)/12)*12 +
        MOD(FLOOR(MONTHS_BETWEEN(SYSDATE, birth_dt)), 12)
    )) AS days
FROM employees;

4. 閏年判斷


-- 方法 1:2 月最後一天是否 29
CASE WHEN TO_CHAR(LAST_DAY(TO_DATE('02'||:yr,'MMYYYY')), 'DD') = '29' THEN 1 ELSE 0 END

-- 方法 2:年份規則
CASE WHEN MOD(:yr, 400) = 0 OR (MOD(:yr, 4) = 0 AND MOD(:yr, 100) != 0) THEN 1 ELSE 0 END

5. 分頁時間窗口(避免隱式轉換導致索引失效)


-- 錯誤:WHERE create_dt > '2024-01-01'  -- 字符串隱式轉換
-- 正確:
WHERE create_dt >= TO_DATE('2024-01-01', 'YYYY-MM-DD')
  AND create_dt <  TO_DATE('2024-02-01', 'YYYY-MM-DD')  -- 閉區間 [start, end)

6. 時區感知轉換(11g+ 推薦)


-- 將 UTC 時間戳轉為上海時間
SELECT CAST(FROM_TZ(CAST(utc_ts AS TIMESTAMP), 'UTC') AT TIME ZONE 'Asia/Shanghai' AS TIMESTAMP)
FROM events;

-- 會話時區設置
ALTER SESSION SET TIME_ZONE = 'Asia/Shanghai';

7. 脫敏:只保留年月


SELECT TO_CHAR(birth_dt, 'YYYY-MM') FROM patients;  -- 2024-05

常見陷阱與避坑

陷阱現象規避
隱式轉換WHERE dt = '2024-01-01' 導致全表掃描強制 TO_DATE + 格式模型
RRRR vs YYYY兩位年份 99→1999, 01→2001 (RRRR) vs 0099/0001 (YYYY)業務明確用 YYYY,模糊輸入用 RRRR
NLS_DATE_LANGUAGETO_CHAR 產出中文/英文月份不一致顯式 'NLS_DATE_LANGUAGE=AMERICAN' 或 ALTER SESSION
TIMESTAMP 精度丟失DATE 只存秒,毫秒截斷關鍵業務用 TIMESTAMP(6)
夏令時缺口/重複時區轉換出現 2:30 不存在或兩次用 TIMESTAMP WITH TIME ZONE + 區域名 (Asia/Shanghai 無夏令時)

總結

日期時間處理的核心原則:**顯式格式模型、顯式時區、優先用 TIMESTAMP WITH TIME ZONE、索引友好寫法(閉區間)、閏年/夏令時邊界測試**。掌握上述 27 函數與格式元素,覆蓋 99% 業務場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved