TO_DATE格式(以時間:2007-11-02 13:45:25為例)
創(chuàng)新互聯(lián)專注于企業(yè)全網(wǎng)營銷推廣、網(wǎng)站重做改版、息縣網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、H5高端網(wǎng)站建設(shè)、購物商城網(wǎng)站建設(shè)、集團公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為息縣等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。
Year:
yy two digits 兩位年 顯示值:07
yyy three digits 三位年 顯示值:007
yyyy four digits 四位年 顯示值:2007
Month:
mm number 兩位月 顯示值:11
mon abbreviated 字符集表示 顯示值:11月,若是英文版,顯示nov
month spelled out 字符集表示 顯示值:11月,若是英文版,顯示november
Day:
dd number 當月第幾天 顯示值:02
ddd number 當年第幾天 顯示值:02
dy abbreviated 當周第幾天簡寫 顯示值:星期五,若是英文版,顯示fri
day spelled out 當周第幾天全寫 顯示值:星期五,若是英文版,顯示friday
ddspth spelled out, ordinal twelfth
Hour:
hh two digits 12小時進制 顯示值:01
hh24 two digits 24小時進制 顯示值:13
Minute:
mi two digits 60進制 顯示值:45
Second:
ss two digits 60進制 顯示值:25
其它
Q digit 季度 顯示值:4
WW digit 當年第幾周 顯示值:44
W digit 當月第幾周 顯示值:1
oracle的date時間類型是 '2011-7-30 14:31'這種形式
因此就算你用extract()或者to_char()截取時間段也沒有沒辦法區(qū)分周
我建議的方法是新建一個字段week,從時間里截取月和日去計算周,可以從每月的第一天00:00開始算,完成7天算一周。
也就是說這個字段week下要有至少4條記錄,分別是每一個月的第一二三四周。
然后根據(jù)這個字段用 group by week 去分組就行了。
[Oracle] 日期處理
本篇是針對以上一篇中 “獲取日期的星期” 部分的展開。
計算標準
Oracle 里支持兩種標準的時間, 一種是oracle 自身的標準, 另一種是ISO 的標準1. oralce 標準
1) 每年的 1 月1號作為這一年的第一天。(不管這一天是星期幾)比如: 2013/01/01 是星期二, 這一天作為2013年的第一天。
2) 周數(shù)計算公式 week = int(dayOfYear+6)/7 ; dayOfYear 是這一天是這一年的第幾天3) 周數(shù)區(qū)間: 1-53
2. ISO標準
1)每個星期總是從周一開始,周日結(jié)束
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 .
其實原因很簡單, 根據(jù)上面的標準, 1998年1月1日是周四,則這一周算為新年的第一周,因為這周的大部分時間屬于1998. 所以1997/12/31 也屬于1998 年的第一周, 所以得到的是 1998.
你可能會想:
這是否因因為上面把字串轉(zhuǎn)為日期的時候使用了YYYY這種格-- TO_DATE('1997/12/31','YYYY/MM/DD'), 如果使用TO_DATE('1997/12/31','IYYY/MM/DD'), 'IYYY') 是否可以? 不幸的是, oracle 不支持這種用法。
假設(shè)當天是 1997/12/31 , 使用 TO_CHAR(sysdate,'IYYY') , 發(fā)現(xiàn)同樣獲得的是 1998.
總結(jié)一下: 如果從string 轉(zhuǎn)換為日期, 如果只取這個日期的年份的話, 最好使用 YYYY。
Oracle 獲取周數(shù)
要獲取某一天是這一年的第幾周, 同樣有兩種標準的區(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
不過這種標準在一般的公司使用的應(yīng)該會比較少。
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 年的第一周。
需要特別提醒的是:(本篇的精華)
年份 和 周數(shù)要使用同樣的標準, 不要混著使用,比如 : YYIW -- oracle 的年份, ISO的周數(shù)IYWW
否則的話, 會得到一些錯誤的結(jié)果。
[sql] view plain copy 在CODE上查看代碼片派生到我的代碼片select TO_CHAR(TO_DATE('1997/12/31','YYYY/MM/DD'), 'YYIW') from dual;返回:9701
整整少了一年。
而且這種錯誤在不跨年的狀況上你可能還不會發(fā)現(xiàn), 一跨年, 發(fā)現(xiàn)又回到了一年前 ^^
有幾周,把每個月的最后一天拼成串傳到如下SQL:
select to_char(to_date('20111031','yyyymmdd'),'w') from dual;
每周日期段沒找到直接的,可以自己寫個函數(shù):
1、獲取1號是周幾,如周4;
2、則1-4號為第一周,即1號+(7-4)天=4號;
3、循環(huán):4+1=5號——4+7=11號為第二周;
直到:某周加完后的日期,大于該月的最大天數(shù),則取該月最大天數(shù)收尾,循環(huán)結(jié)束;
第二種方法是你建個存日期的表:
date week
……
20110101
20110102
……
里面存N年的日期,然后根據(jù)
select to_char(to_date('20111031','yyyymmdd'),'w') from dual; 把week字段update進去;
然后直接根據(jù)這張表寫SQL就直接獲取幾周,每周是幾號到幾號了。。。
給分吧,沒啥說的。
select v_date_month,v_date_min,v_date_max,v_count /*該周在本月中的天數(shù)*/,
rownum - min(rownum) over(partition by v_date_month) + 1 v_zhou_seq /*本月中的第幾周*/
from (
select to_char(v_date, 'yyyymm') v_date_month,
min(v_date) v_date_min,
max(v_date) v_date_max,
count(1) v_count
from (
--使用開窗函數(shù)對2010年全年周進行先后順序的排序
select min(s_rownum) over(partition by rn) rn, a.v_date
from (select rownum s_rownum, to_char(v_date, 'iw') rn, v_date /*, v_date + 7*/ /*, v_zhou*/
from (
--取到2010年全年對應(yīng)的星期幾
select to_date('2010' || '0101', 'yyyymmdd') + rownum - 1 v_date,
to_char(to_date('2010' || '0101', 'yyyymmdd') + rownum - 1, 'day') v_zhou
from (
--取2010年的天數(shù),并排序
select rownum
from dual
connect by rownum = to_date('2010' || '1231', 'yyyymmdd') -
to_date('2010' || '0101', 'yyyymmdd') + 1
)
)
order by v_date) a
order by v_date
)
group by to_char(v_date, 'yyyymm'), rn
order by rn
);
世紀CC2 位的世紀
SCC2 位的世紀。如果是公元前則有一個負號(-)季度Q1 位的季度
年份YYYY完整的 4 位年份
IYYY完整的 4 位 ISO 年份
RRRR完整的 4 位取整年份,其值取決于當前的年份。
SYYY完整的 4 位年份,公元前年份有一個負號(-)Y,YYY完整的 4 位年份,第一個數(shù)字后采用逗號作為分隔符YYY年份的最后 3 位 數(shù)字
IYYISO 年份的最后 3 位數(shù)字
YY年份的最后 2 位數(shù)字
IYISO 年份的最后 2 位數(shù)字
RR取整年份的最后兩位數(shù)字,其值取決于當前的年份。
Y年份的最后一個數(shù)字
IISO 年份的最后一位數(shù)字
YEAR年份全拼,全部大寫
Year年份全拼,首字母大寫
月MM本年中 2 位的月份
MONTH月份的全拼,全部大寫,右端補齊空格,總長為 9 個字符Month月份的全拼,首字母大寫,右端補齊空格,總長為 9 個字符MON月份的前 3 個字母,全部大寫
Mon月份的前 3 個字母,首字母大寫
RM表示月份的羅馬數(shù)字
周WW本年中第幾周,2 位數(shù)字
IW本年中的第幾個 ISO 周,2 位數(shù)字
W本月中的第幾周,1 位數(shù)字
日DDD本年中的第幾天,3 位數(shù)字
DD本月中的第幾天,2 位數(shù)字
D本周中的第幾天,1 位數(shù)字
DAY周幾的全拼,全部大寫
Day周幾的全拼,首字母大寫
DY周幾的前三個字母,全部大寫
Dy周幾的前三個字母,首字母大寫
J公歷日--從公元前 4713 年 1 月 1 日至今已經(jīng)經(jīng)過的天數(shù)時HH2424 小時格式的小時數(shù),2 位數(shù)字
HH12 小時格式的小時數(shù),2 位數(shù)字
分MI2 位的分鐘數(shù)
秒SS2 位的秒數(shù)
FF[1..9]帶有小數(shù)的秒數(shù),小數(shù)點右邊的位數(shù)可選。這只適用于時間戳SSSSS從 12 A.M. 以來經(jīng)過的秒數(shù)
MS毫秒(千分之一秒)數(shù)
CS厘秒(百分之一秒)數(shù)
分隔符-/,.;:用來分割日期和時間各部分的分隔符;可以使用引號來指定任何文本作為分隔符后綴AM 或 PM根據(jù)時間自動設(shè)置為 AM 或 PM
A.M. 或 P.M.根據(jù)時間自動設(shè)置為 A.M. 或 P.M.
AD 或 BC根據(jù)時間自動設(shè)置為 AD 或 BC
A.D. 或 B.C.根據(jù)時間自動設(shè)置為 A.D. 或 B.C.
TH數(shù)字的后綴。如果在數(shù)字格式中采用的是大寫,那么后綴就是大寫;反之,如果在數(shù)字格式中采用的是小寫,那么后綴就是小寫SP數(shù)字的拼寫形式
SPTHTH 和 SP 的組合
紀元EE日本黃歷、臺灣日歷以及泰國佛歷的紀元全名E紀元名簡寫
時區(qū)TZH時區(qū)小時
TZM時區(qū)分
TZR時區(qū)
TZD采用夏令時的時區(qū)
Oracle 對 2 位年份的處理
YY如果日期中的年份采用的格式為 YY,并且只提供了 2 位的年份,那么就認為這一年的世紀與數(shù)據(jù)庫服務(wù)器上當前設(shè)置的世紀相同。
RR如果日期中的年份采用的格式為 RR,并且
只提供了 2 位的年份,那么年份中的前兩位數(shù)字就由兩部分共同確定:提供年份的兩位數(shù)字,數(shù)據(jù)庫服務(wù)器上當前日期中的年份的最后 2 位數(shù)字。
建議:使用 4 位 YYYY 或 RRRR 年份處理,不會引起混淆。