Oracle 日期運算是開發與報表的高頻需求。本文匯總秒/分/時/天/月/年加減、月末/周初/年末邊界計算、工作日算法,代碼即拿即用。
一、基礎時間加減(以 SYSDATE 為基準)
| 需求 | 表達式 | 原理 |
| +5 秒 | SYSDATE + 5/24/60/60 | 1 天 = 24h × 60m × 60s |
| +5 分鐘 | SYSDATE + 5/24/60 | |
| +5 小時 | SYSDATE + 5/24 | |
| +5 天 | SYSDATE + 5 | 日期 + 數字 = 天數 |
| -5 月 | ADD_MONTHS(SYSDATE, -5) | 月份邊界自動處理 |
| -5 年 | ADD_MONTHS(SYSDATE, -5*12) | |
二、邊界日期計算
| 需求 | SQL |
| 上月末日期 | LAST_DAY(ADD_MONTHS(SYSDATE, -1)) |
| 本月最後一秒 | TRUNC(ADD_MONTHS(SYSDATE, 1), 'MM') - 1/24/60/60 |
| 本周一日期 | TRUNC(SYSDATE, 'DAY') + 1 |
| 年初至今天數 | CEIL(SYSDATE - TRUNC(SYSDATE, 'YEAR')) |
| 今年第幾周 | TO_CHAR(SYSDATE, 'FMWW') |
| 本月第幾周 | TO_CHAR(SYSDATE,'WW') - TO_CHAR(TRUNC(SYSDATE,'MM'),'WW') + 1 |
| 本月天數 | TO_CHAR(LAST_DAY(SYSDATE), 'DD') |
| 今年天數 | ADD_MONTHS(TRUNC(SYSDATE,'YEAR'),12) - TRUNC(SYSDATE,'YEAR') |
| 下個周一 | NEXT_DAY(SYSDATE, 'MONDAY') |
三、工作日計算算法(排除週末)
-- 測試數據
CREATE TABLE t (s DATE, e DATE);
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD';
INSERT INTO t VALUES ('2003-03-01','2003-03-03');
INSERT INTO t VALUES ('2003-03-02','2003-03-03');
INSERT INTO t VALUES ('2003-03-07','2003-03-08');
INSERT INTO t VALUES ('2003-03-07','2003-03-09');
INSERT INTO t VALUES ('2003-03-05','2003-03-07');
INSERT INTO t VALUES ('2003-02-01','2003-03-31');
-- 核心查詢:總天數 + 工作日
SELECT s, e,
e - s + 1 AS total_days,
TRUNC((e - s + 1)/7)*5 +
LENGTH(REPLACE(SUBSTR('01111100111110',
TO_CHAR(s,'D'), MOD(e-s+1,7)), '0','')) AS work_days
FROM t;
-- 邏輯解析:
-- '01111100111110' 為 14 位掩碼:索引 1=周日(0) ... 7=周六(0),雙周循環
-- TO_CHAR(s,'D') 取起始星期數 (1-7)
-- MOD(e-s+1,7) 取餘數天數
-- SUBSTR 截取對應掩碼片段,REPLACE 去掉 '0',LENGTH 剩餘長度即工作日數
四、日期格式模板速查
YYYY 四位年 YEAR 年度拼寫
MM 兩位月 MONTH 月份全拼
DD 兩位日 DAY 星期全拼 DY 星期縮寫
HH24 24制時 MI 分 SS 秒
FM 填充模式關閉(去除前導零/空格)