這個算法的結果依賴于當前系統(tǒng)時間是什么時候…假設按照你說的,當前系統(tǒng)時間是星期六,那么它計算的結果就是說這個星期六是本月的第幾個星期六。就拿12月來說,12月1日是星期六哦,所以你在12月1號查的時候它結果會是1哦,但是12月2日的時候,你查周日,它的結果仍然是1哦,因為是本月第一次出現的星期日哦!只有當你查12月8日的時候,才開始出現結果2哦…其實你可以在系統(tǒng)里選一些特殊的時間查一下就可以發(fā)現規(guī)律
豐寧網站制作公司哪家好,找成都創(chuàng)新互聯!從網頁設計、網站建設、微信開發(fā)、APP開發(fā)、成都響應式網站建設公司等網站項目制作,到程序開發(fā),運營維護。成都創(chuàng)新互聯從2013年成立到現在10年的時間,我們擁有了豐富的建站經驗和運維經驗,來保證我們的工作的順利進行。專注于網站建設就選成都創(chuàng)新互聯。
[Oracle] 日期處理
本篇是針對以上一篇中 “獲取日期的星期” 部分的展開。
計算標準
Oracle 里支持兩種標準的時間, 一種是oracle 自身的標準, 另一種是ISO 的標準1. oralce 標準
1) 每年的 1 月1號作為這一年的第一天。(不管這一天是星期幾)比如: 2013/01/01 是星期二, 這一天作為2013年的第一天。
2) 周數計算公式 week = int(dayOfYear+6)/7 ; dayOfYear 是這一天是這一年的第幾天3) 周數區(qū)間: 1-53
2. ISO標準
1)每個星期總是從周一開始,周日結束
2)如果1月1日是周五、周六或周日,則這一周算為上一年的最后一周,因為這周的大部分時間屬于上一年3)如果1月1日是周一、周二、周三或周四,則這一周算為新年的第一周,因為這周的大部分時間屬于新的一年4)時間區(qū)間: 1-52 or 1-53
舉例來說: 對于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 標準 - YYYY
oralce 標準獲取年份的方式很簡單:
[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 標準 - 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 號的年份是 1998 .
其實原因很簡單, 根據上面的標準, 1998年1月1日是周四,則這一周算為新年的第一周,因為這周的大部分時間屬于1998. 所以1997/12/31 也屬于1998 年的第一周, 所以得到的是 1998.
你可能會想:
這是否因因為上面把字串轉為日期的時候使用了YYYY這種格-- TO_DATE('1997/12/31','YYYY/MM/DD'), 如果使用TO_DATE('1997/12/31','IYYY/MM/DD'), 'IYYY') 是否可以? 不幸的是, oracle 不支持這種用法。
假設當天是 1997/12/31 , 使用 TO_CHAR(sysdate,'IYYY') , 發(fā)現同樣獲得的是 1998.
總結一下: 如果從string 轉換為日期, 如果只取這個日期的年份的話, 最好使用 YYYY。
Oracle 獲取周數
要獲取某一天是這一年的第幾周, 同樣有兩種標準的區(qū)別:
1. oracle 標準 - WW
這種標準和算法看起來很傻瓜。 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;很簡單; 返回 9701 ,9702,9753
不過這種標準在一般的公司使用的應該會比較少。
2. iso 標準 - 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 年的第一周。
需要特別提醒的是:(本篇的精華)
年份 和 周數要使用同樣的標準, 不要混著使用,比如 : YYIW -- oracle 的年份, ISO的周數IYWW
否則的話, 會得到一些錯誤的結果。
[sql] view plain copy 在CODE上查看代碼片派生到我的代碼片select TO_CHAR(TO_DATE('1997/12/31','YYYY/MM/DD'), 'YYIW') from dual;返回:9701
整整少了一年。
而且這種錯誤在不跨年的狀況上你可能還不會發(fā)現, 一跨年, 發(fā)現又回到了一年前 ^^
這樣就可以?。?/p>
select?to_char(sysdate,'w')?from?dual;
今天就是本月的第三周。
with t as(select date'2015-1-1'+level-1 as dt from dual connect by level=365)
select dt,to_char(dt,'w') as w,to_char(dt,'day') as d,
trunc((to_char(dt,'dd')+to_char(last_day(add_months(dt,-1)),'d')-1) /7) +1 as e from t;
希望這個能滿足你的要求!
SELECT to_char(SYSDATE,'iw') -to_char(last_day(add_months( SYSDATE,-1))+1,'iw')+1 FROM DUAL;
這樣統(tǒng)計出來的每月的1號所在的周為第一周
獲取月(兩位):select to_char(sysdate,'mm') from dual
那你就把指定的日期to_date()成date,如下:
select to_char(to_date('2004-05-07 13:23:44','yyyy-mm-dd hh24:mi:ss'),'mm') from dual