Oracle日期周詳解以及周開始結束時間計算

1 ORACLE中周相關知識描述

1.1           日期格式化函數

TO_CHAR(X [,FORMAT]):將X按FORMAT格式轉換成字符串。X是一個日期,FORMAT是一個規定了X採用何種格式轉換的格式字符串,FORMAT與周相關的有W,WW,IW,D,FMWW。算法

W 的含義是一個月的第幾周。是按照ORACLE自定義的標準周來返回週數。sql

IW是ISO標準周,它的含義是ISO標準周以周別爲「主線」,每一年最多能夠有53個周別,可是每一年至少要包含52個周別;若是一年當中第52周別以後至當年的12月31日之間,還有大於或等於4天的話,則定爲當年的第53周,不然剩餘這些天數被歸爲下一年的第1周;若是在不足52周別的話,則如下一年的時間來補;每週固定的從週一開始做爲本週的第1天,到週日做爲本週的第7天;好比:在Oracle中 2012年01月01號依然屬於IW周別2011年的第52周的第7天。這個用到的比較多。函數

WW是ORACLE自定義的標準周,它的含義是每一年的1月1日做爲當年的第一週的第一天(無論當年的1月1日是星期幾);好比:2014年01年01是週三,在Oracle中被定義爲2014年WW的第一週的第一天。通常不多用到。spa

D是返回當前日期是這個星期的第幾天。是按照從週日到週六來進行計算的,這是要注意的地方。code

FMWW該年1月1號(不考慮屬星期幾)開始至該年該一個星期日爲第一週,第二週是從該年第一個星期開始算(這與IW算法相同)一年的最後一週以該年的12月31號作爲截止。字符串

1.2           日期時間運算函數

NEXT_DAY(X,Y):用於計算X時間後第一個星期Y的時間。Y是一個字符串,表示用當前會話語言表示的一週中某一天的全稱(如星期1、星期二等),也能夠是數值。class

TRUNC(X [,FORMAT]):截斷日期, FORMAT 中與周相關的有D,IW,WW,W,FMWW。語言

W 的含義是一個月的第幾周。是按照ORACLE自定義的標準周來返回的是一個週數。時間

IW是ISO標準周,返回是的當前日期所在周的週一。co

WW是ORACLE自定義的標準周。返回ORACLE自定義標準周所在的週一。

的含義是的返回當前星期的第一天。使人感到奇怪的是根據D返回的是當前星期的第一天是星期日。這點是咱們要注意的地方。

FMWW該年1月1號(不考慮屬星期幾)開始至該年該一個星期日爲第一週,第二週是從該年第一個星期開始算(這與IW算法相同)一年的最後一週以該年的12月31號作爲截止。取周的開始時間時在跨年的時候與IW有些區別,好比2012年01年01使用FMWW的時候,周的開始時間是2012-01-01,使用IW時,周的開始時間是2011/12/26。

ROUND(X [,FORMAT]):日期的四捨五入FORMAT中與周相關的有DAY。按週一到週三和週四到週日四捨五入到最近的週日。

2 根據給定時間取一週的開始時間和結束時間

--取周的開始時間和結束時間  
SELECT TRUNC(TO_DATE('2014-07-18','YYYY-MM-DD'),'IW') AS STARTDATE FROM DUAL;--本週週一  
SELECT TRUNC(TO_DATE('2014-07-18','YYYY-MM-DD'),'IW') + 6 AS ENDDATE FROM DUAL;--本週週日  
  
SELECT TRUNC(TO_DATE('2014-07-18','YYYY-MM-DD'),'IW') - 7 AS STARTDATE FROM DUAL;---上週週一     
SELECT TRUNC(TO_DATE('2014-07-18','YYYY-MM-DD'),'IW') - 1  AS ENDDATE FROM DUAL;--上週週日

 

 

3 根據給定週數取一週的開始時間和結束時間

 

取天然周的開始時間和結束時間的難點就須要判斷年初的那幾天是屬於本年的第一週,仍是屬於上一年的最後一週,根據IW天然周的定義,少於等於3天是本年的話,屬於上一年的最後一週,大於等於4天屬於本年的話,加上上年的最後幾天,算成本年的第一週。

--按照週一到週日爲一週算周的開始時間和結束時間(IW)天然周  
WITH PARAMS AS (SELECT TRUNC(TO_DATE('2009-01-01','YYYY-MM-DD'),'YYYY') AS SD FROM DUAL)  
SELECT LEVEL 周次,  
DECODE(SIGN(5-DECODE(TO_CHAR(PM.SD,'D'),'1','7',TO_CHAR(PM.SD,'D'))),-1,  
NEXT_DAY(PM.SD+(LEVEL-1)*7,2),NEXT_DAY(PM.SD+(LEVEL-1)*7-7,2))  
 當週第一天,  
DECODE(SIGN(5-DECODE(TO_CHAR(PM.SD,'D'),'1','7',TO_CHAR(PM.SD,'D'))),-1,  
NEXT_DAY(PM.SD+(LEVEL-1)*7,2),NEXT_DAY(PM.SD+(LEVEL-1)*7-7,2)) + 6  
當週最後一天  
FROM DUAL D  
LEFT JOIN PARAMS PM ON 1=1  
CONNECT BY LEVEL<=53  

--按照週日到週六爲一週算周的開始時間和結束時間(D)  
SELECT LEVEL 周次,(TRUNC(TO_DATE('2011-01-01','YYYY-MM-DD'),'YYYY')-7) + (7-TO_CHAR(TRUNC(TO_DATE('2011-01-01','YYYY-MM-DD'),'YYYY'),'D')+1)+(LEVEL-1)*7  當週第一天,  
    (TRUNC(TO_DATE('2011-01-01','YYYY-MM-DD'),'YYYY')-7) + (7-TO_CHAR(TRUNC(TO_DATE('2011-01-01','YYYY-MM-DD'),'YYYY'),'D')+1)+(LEVEL-1)*7+6 當週最後一天  
FROM DUAL CONNECT BY LEVEL<=53  

--按照ORACLE標準(WW)  
SELECT LEVEL 周次,TO_DATE('2013-01-01','YYYY-MM-DD')+(LEVEL-1)*7  當週第一天,  
    TO_DATE('2013-01-01','YYYY-MM-DD')+(LEVEL-1)*7+  
    DECODE((TO_CHAR(TO_DATE('2013-12-31','YYYY-MM-DD'),'DDD')-(LEVEL-1)*7),1,0,2,1,6) 當週最後一天  
FROM DUAL CONNECT BY LEVEL<=53

 

4 獲取一年的最大周次

--獲取一年中的最大周次(IW)中國日曆天然周  
WITH PARAMS AS (SELECT '2014' AS NF FROM DUAL)  
SELECT TO_CHAR(TO_DATE(PM.NF || '-12-28','YYYY-MM-DD'),'IYYYIW') FROM DUAL LEFT JOIN PARAMS PM ON 1=1

 

上述SQL經過卡每一年的12月28號屬於哪一個周,也判斷一年有多少個天然周。

 

5   特別應該注意的地方

 

取周別的時候最好把年份帶上,第一由於周別是相對於哪年的第幾周,第二由於當使用IW的時候對於一年的開始那幾天和結束那幾天可能會產生同樣的週數,就分不清屬於哪年的第一週。

相關文章
相關標籤/搜索