Oracle中几个日期相关的计算
1. 计算当前是第几周
有两种方式:
select to_char(sysdate,'ww') from dual; --ww的算法为每年1月1日为第一周开始,date+6为每一周结尾 --例如:20050101为第一周的第一天,而第一周的最后一天为20050101+6=20050107 --这里1月1日不一定为周一,月7日也不一定为周日 select to_char(sysdate,'iw') from dual; --iw的算法为星期一至星期日算一周,且每年的第一个星期一为第一周, --这种算法,需要关注跨年的那个一周: --假如跨年的一周,大部分时间属于新年,则上一年的最后几天也算新年的第一周 --比如20130101 是周二,那么2012年的最后几天 都属于2013年的第一周 select to_char(to_date('20130101','yyyymmdd'),'iw') from dual; --01 select to_char(to_date('20121231','yyyymmdd'),'iw') from dual; --01 --假如跨年一周,大部分时间在上年,则跨年周中新年的前几天 属于上年的最后一周 --2020年12月31号是周4,这样跨年的那一周有4天在2020年,所以上面的输出为53 select to_char(to_date('20201231','yyyymmdd'),'iw') from dual; --53 select to_char(to_date('20210101','yyyymmdd'),'iw') from dual; --53 --2021年的前面几天 还是属于 上年的最后一周(53)周
2. 计算上周一 和 上周日的日期
根据中国习惯,一周从周一到周日.
prompt 'week_date_beg_end' create or replace procedure week_date_beg_end ( the_date varchar2 ) as a_date date; v_i_tmp number(10); v_tmp_date_beg number(10); v_tmp_date_end number(10); begin a_date := to_date(the_date,'yyyymmdd'); v_i_tmp := to_number(to_char(a_date,'D')); --指定日期的星期,1-7表示周日 - 周六 if v_i_tmp = 1 then -- 表示指定日期是周日 v_i_tmp := 6; -- v_i_tmp 表示指定日期 距离本周一的天数 else v_i_tmp := v_i_tmp - 2; -- v_i_tmp 表示指定日期 距离本周一的天数 end if; v_tmp_date_beg := to_number(to_char(a_date - v_i_tmp - 7,'YYYYmmDD')); --指定日期 的 上周一 v_tmp_date_end := to_number(to_char(a_date - v_i_tmp - 1,'YYYYmmDD')); --指定日期 的 上周日 dbms_output.put_line(v_tmp_date_beg); dbms_output.put_line(v_tmp_date_end); end; / --pl sql developer中测试 set serverout on; exec week_date_beg_end('20130505'); -- 输出为: -- 20130422 -- 20130428 -- PL/SQL procedure successfully completed
另,博客 http://blog.csdn.net/limenghua9112/article/details/11193819?reload
中提供的方法不对
-- 这样取的是 在一周内第几天,是以周日为开始的
select to_char(to_date('20130906','yyyymmdd'),'d') from dual;
--结果:6 注释:2013.09.06是周五,为本周的第六天
select to_char(sysdate+(2-to_char(sysdate,'d'))-7,'yyyymmdd') from dual;---上周一
select to_char(sysdate+(2-to_char(sysdate,'d'))-1,'yyyymmdd') from dual;---上周日
--这种算法中,当当前日期为周日时,算出来的上周日还是当天,貌似不对.
--比如,20130505是周日,下面的语句输出的还是 20130505
select to_char(to_date('20130505','yyyymmdd')+(2-to_char(to_date('20130505','yyyymmdd'),'d'))-1,'yyyymmdd') from dual;
3. 计算 上月的第一天 和 最后一天 日期
v_tmp_date_beg := to_number(to_char(last_day(add_months(sysdate,-2)) + 1,'yyyymmdd')); --上月第一天 v_tmp_date_end := to_number(to_char(last_day(add_months(sysdate,- 1)),'yyyymmdd')); --上月最后一天