首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

Oracle 日期運算與工作日計算實戰:從基礎加減到業務級算法

     編輯:Oracle 資料庫基礎

日期運算貫穿業務系統始終。本文分兩部份:第一部份匯總秒/分/時/天/月/年加減、邊界日期(月末、周初、年末)、格式模板;第二部份給出生產級工作日計算算法(排除週末),附帶測試數據與邏輯解析,可直接嵌入存儲過程或報表 SQL。

一、基礎時間加減速查表

需求表達式
+5 秒SYSDATE + 5/24/60/60
+5 分鐘SYSDATE + 5/24/60
+5 小時SYSDATE + 5/24
+5 天SYSDATE + 5
-5 月ADD_MONTHS(SYSDATE, -5)
-5 年ADD_MONTHS(SYSDATE, -60)

二、邊界日期計算

需求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')

三、工作日計算算法(生產級)

-- 假設日期無時間分量,否則所有日期前加 TRUNC
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;
DROP TABLE t;

四、算法邏輯深度解析

  1. 完全周數:TRUNC((天數)/7)*5,每周 5 個工作日。
  2. 餘數天數掩碼:'01111100111110' 為 14 位雙周掩碼
    • 索引 1=周日(0)、2=周一(1)...7=周六(0)、8=周日(0)...14=周六(0)
    • 周一至周五為 1(工作日),周六周日為 0
  3. 起始偏移:TO_CHAR(s,'D') 返回 1(周日)~7(周六),作為掩碼起始索引。
  4. 截取長度:MOD(天數,7) 為餘數天數。
  5. 計數:SUBSTR 截取片段 → REPLACE(...,'0','') 移除周末 → LENGTH 剩餘長度即工作日數。

該算法無需日歷表,純 SQL 實現,性能極高,適合百萬級報表實時計算。

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