oracle周數(shù)計(jì)算
創(chuàng)新互聯(lián)是一家專注于網(wǎng)站制作、網(wǎng)站設(shè)計(jì)與策劃設(shè)計(jì),旌陽(yáng)網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)10余年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:旌陽(yáng)等地區(qū)。旌陽(yáng)做網(wǎng)站價(jià)格咨詢:18982081108
===========================================================
作者: keyneslin()
發(fā)表于: :
分類: ORACLE
出處:
================================================
日期計(jì)算 算第n周的第一天及最后一天是幾號(hào) ? by keynes
================================================
ww的算法為每年 月 日為第一周開始 date+ 為每一周結(jié)尾
例如 為第一周的第一天 而第一周的最后一天為 + =
公式 每周第一天? date + 周 *
每周最后一天 date + 周 *
不管怎么編排格式都會(huì)跑掉 真氣人 ~~
=========================================================================
日期計(jì)算 算第n周的第一天及最后一天是幾號(hào) ? by keynes
=========================================================================
ww的算法為每年 月 日為第一周開始 date+ 為每一周結(jié)尾
例如 為第一周的第一天 而第一周的最后一天為 + =
公式 每周第一天? date + 周 *
每周最后一天 date + 周 *
如果以ww格式為主 第 周的起迄如下
:asdb:WFselect to_date( yyyymmdd ) + * to_date( yyyymmdd ) + * from dual;
TO_DATE( TO_DATE(
JAN JAN
:asdb:WFselect to_date( yyyymmdd ) + * to_date( yyyymmdd ) + * from dual;
TO_DATE( TO_DATE(
APR APR
Elapsed: : :
驗(yàn)證如下
:asdb:WFselect to_char(to_date( yyyymmdd ) ww ) as weekn to_char(to_date( yyyymmdd ) ww ) as week to_char(to_date( yyyymmdd ) ww ) as week to_char(to_date( yyyymmdd ) ww ) as weekn from dual;
WEEK WEEK WEEK WEEK
??
Elapsed: : :
:asdb:WF
iw的算法為星期一至星期日算一周 且每年的第一個(gè)星期一為第一周
例如 為星期六 所以用iw的算法是前年的 周 而 之后才是第一周的開始
公式 每周第一天? next_day(date) + 周 *
每周最后一天 next_day(date) + 周 *
如果以iw格式為主 第 周的起迄如下
:asdb:WFselect next_day(to_date( yyyymmdd ) MONDAY )+ * as first_day next_day(to_date( yyyymmdd ) MONDAY )+ * as last_day from dual;
FIRST_DAY LAST_DAY
JAN JAN
Elapsed: : :
:asdb:WF
:asdb:WFselect next_day(to_date( yyyymmdd ) MONDAY )+ * as first_day next_day(to_date( yyyymmdd ) MONDAY )+ * as last_day from dual;
FIRST_DAY LAST_DAY
APR MAY
Elapsed: : :
:asdb:WF
驗(yàn)證如下
:asdb:WFselect to_char(to_date( yyyymmdd ) iw ) as weekn to_char(to_date( yyyymmdd ) iw ) as week to_char(to_date( yyyymmdd ) iw ) as week to_char(to_date( yyyymmdd ) iw ) as weekn from dual;
WEEK WEEK WEEK WEEK
??
Elapsed: : :
其它
== 查今天是 本月 的第幾周
SELECT TO_CHAR(SYSDATE WW ) TO_CHAR(TRUNC(SYSDATE MM ) WW ) + AS weekOfMon from dual;
或
SELECT TO_CHAR(SYSDATE W ) AS weekOfMon from dual;
== 查今天是 今年 的第幾周
select to_char(sysdate ww ) from dual;
或
select to_char(sysdate iw ) from dual;
附注
上文所提之iw及ww格式在doc內(nèi)解釋如下
IW = Week of year ( or ) based on the ISO standard
WW = Week of year ( ) where week starts on the first day of the year and continues to the seventh day of the year
參考文件
Format Models
oracle周數(shù)計(jì)算(續(xù))
===========================================================
作者: keyneslin()
發(fā)表于: :
分類: ORACLE
出處:
本篇是接續(xù)前一篇 因有朋友(allenc)要計(jì)算oracle的周數(shù)日期起迄
所以測(cè)試了一下
測(cè)試結(jié)果如下
特殊周數(shù)計(jì)算
星期日到星期六為一周(與ww及iw算法不同)
例 年的第一周起迄是同一天 是
例 年的第一周起為 迄為
計(jì)算第一周的天數(shù)
create or replace function fdf(p_date in date) return number
is
begin
檢查是否傳入要計(jì)算那一年的一月一日
if to_char(to_char(p_date ddd )) then
return null;
end if;
如果第一周的第一天剛好也是最后一天時(shí) 傳回
if to_char(p_date d ) then
return (next_day(p_date SATURDAY ) p_date + );
else
return ;
end if;
exception
when others then
dbms_output put_line(sqlerrm);
end;
計(jì)算公式
起??????????? decode(周 計(jì)算當(dāng)年的一月一日 計(jì)算當(dāng)年的一月一日 + (fdf(計(jì)算當(dāng)年的一月一日) + (周 )* )) as 起
迄(第一種算法) decode(周 to_date(to_char(計(jì)算當(dāng)年的一月一日 yyyy )|| || yyyymmdd ) 計(jì)算當(dāng)年的一月一日 + (fdf(計(jì)算當(dāng)年的一月一日) + (周 )* )) as 迄
迄(第二種算法) decode(周 last_day(trunc(計(jì)算當(dāng)年的一月一日 mm )+ ) 計(jì)算當(dāng)年的一月一日 + (fdf(計(jì)算當(dāng)年的一月一日) + (周 )* )) as 迄
上面的參數(shù)部份 計(jì)算當(dāng)年的一月一日 為date type 周 為number type
傳回值一律是date型態(tài)
例如
年第 周
select decode( to_date( yyyymmdd ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as s_week decode( to_date(to_char(to_date( yyyymmdd ) yyyy )|| || yyyymmdd ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as e_week from dual;
年第 周
select decode( to_date( yyyymmdd ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as s_week decode( to_date(to_char(to_date( yyyymmdd ) yyyy )|| || yyyymmdd ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as e_week from dual;
年第 周
select decode( to_date( yyyymmdd ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as s_week decode( to_date(to_char(to_date( yyyymmdd ) yyyy )|| || yyyymmdd ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as e_week from dual;
年第 周
select decode( to_date( yyyymmdd ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as s_week decode( to_date(to_char(to_date( yyyymmdd ) yyyy )|| || yyyymmdd ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as e_week from dual;
年第 周
select decode( to_date( yyyymmdd ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as s_week decode( to_date(to_char(to_date( yyyymmdd ) yyyy )|| || yyyymmdd ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as e_week from dual;
年第 周
select decode( to_date( yyyymmdd ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as s_week decode( to_date(to_char(to_date( yyyymmdd ) yyyy )|| || yyyymmdd ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as e_week from dual;
年第 周方法
select decode( to_date( yyyymmdd ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as s_week decode( last_day(trunc(to_date( yyyymmdd ) mm )+ ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as e_week from dual;
結(jié)果如下
:asdb:WF 年第 周
:asdb:WFselect decode( to_date( yyyymmdd ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as s_week decode( to_date(to_char(to_date( yyyymmdd ) yyyy )|| || yyyymmdd ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as e_week from dual;
S_WEEK??? E_WEEK
JAN JAN
Elapsed: : :
:asdb:WF 年第 周
:asdb:WFselect decode( to_date( yyyymmdd ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as s_week decode( to_date(to_char(to_date( yyyymmdd ) yyyy )|| || yyyymmdd ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as e_week from dual;
S_WEEK??? E_WEEK
JAN JAN
Elapsed: : :
:asdb:WF 年第 周
:asdb:WFselect decode( to_date( yyyymmdd ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as s_week decode( to_date(to_char(to_date( yyyymmdd ) yyyy )|| || yyyymmdd ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as e_week from dual;
S_WEEK??? E_WEEK
DEC DEC
Elapsed: : :
:asdb:WF
:asdb:WF 年第 周
:asdb:WFselect decode( to_date( yyyymmdd ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as s_week decode( to_date(to_char(to_date( yyyymmdd ) yyyy )|| || yyyymmdd ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as e_week from dual;
S_WEEK??? E_WEEK
JAN JAN
Elapsed: : :
:asdb:WF 年第 周
:asdb:WFselect decode( to_date( yyyymmdd ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as s_week decode( to_date(to_char(to_date( yyyymmdd ) yyyy )|| || yyyymmdd ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as e_week from dual;
S_WEEK??? E_WEEK
JAN JAN
Elapsed: : :
:asdb:WF 年第 周
:asdb:WFselect decode( to_date( yyyymmdd ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as s_week decode( to_date(to_char(to_date( yyyymmdd ) yyyy )|| || yyyymmdd ) to_date( yyyymmdd ) + (fdf(to_date( yyyymmdd )) + ( )* )) as e_week from dual;
S_WEEK??? E_WEEK
DEC DEC
Elapsed: : :
lishixinzhi/Article/program/Oracle/201311/18269
[Oracle] 日期處理
本篇是針對(duì)以上一篇中 “獲取日期的星期” 部分的展開。
計(jì)算標(biāo)準(zhǔn)
Oracle 里支持兩種標(biāo)準(zhǔn)的時(shí)間, 一種是oracle 自身的標(biāo)準(zhǔn), 另一種是ISO 的標(biāo)準(zhǔn)1. oralce 標(biāo)準(zhǔn)
1) 每年的 1 月1號(hào)作為這一年的第一天。(不管這一天是星期幾)比如: 2013/01/01 是星期二, 這一天作為2013年的第一天。
2) 周數(shù)計(jì)算公式 week = int(dayOfYear+6)/7 ; dayOfYear 是這一天是這一年的第幾天3) 周數(shù)區(qū)間: 1-53
2. ISO標(biāo)準(zhǔn)
1)每個(gè)星期總是從周一開始,周日結(jié)束
2)如果1月1日是周五、周六或周日,則這一周算為上一年的最后一周,因?yàn)檫@周的大部分時(shí)間屬于上一年3)如果1月1日是周一、周二、周三或周四,則這一周算為新年的第一周,因?yàn)檫@周的大部分時(shí)間屬于新的一年4)時(shí)間區(qū)間: 1-52 or 1-53
舉例來(lái)說(shuō): 對(duì)于1998和1999年的1月1日,1998年是算第一周,而1999年的1月1日卻算為上一年的最后一周。
Table 3-7 First ISO Week of the Year: Example 1, January 1998MoTuWeThFrSaSuISO Week
---12341 ISO week of 1998
5678910112 ISO week of 1998
121314151617183 ISO week of 1998
192021222324254 ISO week of 1998
262728293031-5 ISO week of 1998
Table 3-8 First ISO Week of the Year: Example 2, January 1999MoTuWeThFrSaSuISO Week
----12353 ISO week of 1998
456789101 ISO week of 1999
111213141516172 ISO week of 1999
181920212223243 ISO week of 1999
252627282930314 ISO week of 1999
Oracle中獲取年份
1. oralce 標(biāo)準(zhǔn) - YYYY
oralce 標(biāo)準(zhǔn)獲取年份的方式很簡(jiǎn)單:
[sql] view plain copy 在CODE上查看代碼片派生到我的代碼片select TO_CHAR(TO_DATE('1997/01/01','YYYY/MM/DD'), 'YYYY') from dual;select TO_CHAR(TO_DATE('1997/12/31','YYYY/MM/DD'), 'YYYY') from dual;都是返回 1997
2. iso 標(biāo)準(zhǔn) - IYYY
[sql] view plain copy 在CODE上查看代碼片派生到我的代碼片select TO_CHAR(TO_DATE('1997/01/01','YYYY/MM/DD'), 'IYYY') from dual;select TO_CHAR(TO_DATE('1997/12/31','YYYY/MM/DD'), 'IYYY') from dual;返回: 1997, 1998
是不是很奇怪, 1997/12/31 號(hào)的年份是 1998 .
其實(shí)原因很簡(jiǎn)單, 根據(jù)上面的標(biāo)準(zhǔn), 1998年1月1日是周四,則這一周算為新年的第一周,因?yàn)檫@周的大部分時(shí)間屬于1998. 所以1997/12/31 也屬于1998 年的第一周, 所以得到的是 1998.
你可能會(huì)想:
這是否因因?yàn)樯厦姘炎执D(zhuǎn)為日期的時(shí)候使用了YYYY這種格-- TO_DATE('1997/12/31','YYYY/MM/DD'), 如果使用TO_DATE('1997/12/31','IYYY/MM/DD'), 'IYYY') 是否可以? 不幸的是, oracle 不支持這種用法。
假設(shè)當(dāng)天是 1997/12/31 , 使用 TO_CHAR(sysdate,'IYYY') , 發(fā)現(xiàn)同樣獲得的是 1998.
總結(jié)一下: 如果從string 轉(zhuǎn)換為日期, 如果只取這個(gè)日期的年份的話, 最好使用 YYYY。
Oracle 獲取周數(shù)
要獲取某一天是這一年的第幾周, 同樣有兩種標(biāo)準(zhǔn)的區(qū)別:
1. oracle 標(biāo)準(zhǔn) - WW
這種標(biāo)準(zhǔn)和算法看起來(lái)很傻瓜。 int(dayOfYear+6)/7[sql] view plain copy 在CODE上查看代碼片派生到我的代碼片select TO_CHAR(TO_DATE('1997/01/01','YYYY/MM/DD'), 'YYWW') from dual;select TO_CHAR(TO_DATE('1997/01/08','YYYY/MM/DD'), 'YYWW') from dual;select TO_CHAR(TO_DATE('1997/12/31','YYYY/MM/DD'), 'YYWW') from dual;很簡(jiǎn)單; 返回 9701 ,9702,9753
不過(guò)這種標(biāo)準(zhǔn)在一般的公司使用的應(yīng)該會(huì)比較少。
2. iso 標(biāo)準(zhǔn) - IW
[sql] view plain copy 在CODE上查看代碼片派生到我的代碼片select TO_CHAR(TO_DATE('1997/01/01','YYYY/MM/DD'), 'IYIW') from dual;select TO_CHAR(TO_DATE('1997/12/31','YYYY/MM/DD'), 'IYIW') from dual;返回: 9701,9801
如上所述, 1997/12/31 歸到 1998 年的第一周。
需要特別提醒的是:(本篇的精華)
年份 和 周數(shù)要使用同樣的標(biāo)準(zhǔn), 不要混著使用,比如 : YYIW -- oracle 的年份, ISO的周數(shù)IYWW
否則的話, 會(huì)得到一些錯(cuò)誤的結(jié)果。
[sql] view plain copy 在CODE上查看代碼片派生到我的代碼片select TO_CHAR(TO_DATE('1997/12/31','YYYY/MM/DD'), 'YYIW') from dual;返回:9701
整整少了一年。
而且這種錯(cuò)誤在不跨年的狀況上你可能還不會(huì)發(fā)現(xiàn), 一跨年, 發(fā)現(xiàn)又回到了一年前 ^^
這個(gè)算法的結(jié)果依賴于當(dāng)前系統(tǒng)時(shí)間是什么時(shí)候…假設(shè)按照你說(shuō)的,當(dāng)前系統(tǒng)時(shí)間是星期六,那么它計(jì)算的結(jié)果就是說(shuō)這個(gè)星期六是本月的第幾個(gè)星期六。就拿12月來(lái)說(shuō),12月1日是星期六哦,所以你在12月1號(hào)查的時(shí)候它結(jié)果會(huì)是1哦,但是12月2日的時(shí)候,你查周日,它的結(jié)果仍然是1哦,因?yàn)槭潜驹碌谝淮纬霈F(xiàn)的星期日哦!只有當(dāng)你查12月8日的時(shí)候,才開始出現(xiàn)結(jié)果2哦…其實(shí)你可以在系統(tǒng)里選一些特殊的時(shí)間查一下就可以發(fā)現(xiàn)規(guī)律
比如星期一到星期天算一周 查2011年7月完整周數(shù) select max(count1) - 1 from (SELECT count(1) count1 FROM DUAL WHERE TO_CHAR(ADD_MONTHS(LAST_DAY(to_date('201107', 'yyyyMM')), -1) + LEVEL, 'DAY') = '星期一' CONNECT BY LEVEL