根据输入的日期计算周次和月份

本文介绍了一个Oracle PL/SQL过程,用于将指定日期范围内的日期按周和按月进行划分。该过程考虑了周的定义(从周一到周日),并针对不足7天的情况进行了特殊处理。此外,还提供了示例代码和运行示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求:

1.根据输入的日期拆分成按周或按月显示

2.规定周的开始日期从星期一开始,星期日结束

3.不足7天的一周,如果小于2天,则合并到上周或下周;大于2天的则自成一周

 

代码:

CREATE OR REPLACE PROCEDURE printWeekAndMonth(fromdate in varchar2, todate in varchar2)
IS
   l_getdate VARCHAR2(255) ;--转换后的临时时间
   v_i NUMBER(10);
   l_tmpdate1 VARCHAR2(255);      --临时时间
   l_tmplastdate VARCHAR2(255);   --得到临时当月最后一天
   type v_array IS VARRAY(7) OF VARCHAR2(20);
   v_arr v_array;
BEGIN

  l_tmplastdate:= to_char(LAST_DAY(to_date(fromdate,'YYYY-MM-DD')),'YYYY-MM-DD');


  dbms_output.put_line('=================打印周次====================');

  v_arr := v_array('星期一','星期二','星期三','星期四','星期五','星期六','星期日');
  --如果输入的开始日期为星期一
  if to_char(to_date(fromdate,'yyyy-mm-dd'),'day') = v_arr(1) then
     l_getdate := to_char(to_date(fromdate,'yyyy-mm-dd'),'yyyy-mm-dd');--一周开始日期
  else
    --不为星期一,则计算下个星期一的日期
    for i in 1..v_arr.count loop
        if v_arr(i) = to_char(to_date(fromdate,'yyyy-mm-dd'),'day') then
          --dbms_output.put_line(fromdate || '所在的星期为:' || v_arr(i));
          l_getdate := to_char(to_date(fromdate,'yyyy-mm-dd')+8-i,'yyyy-mm-dd');--一周开始日期
          if i > 5 then --开始日期范围在星期六到星期天,合并到下周
            dbms_output.put_line(to_char(to_date(fromdate,'yyyy-mm-dd'),'yyyy-mm-dd') || '~' || to_char(to_date(l_getdate,'yyyy-mm-dd')+6,'yyyy-mm-dd'));--需要插入到表中...
            l_getdate :=  to_char(to_date(l_getdate,'yyyy-mm-dd')+7,'yyyy-mm-dd');
          else --开始日期范围在星期二到星期五,自成一周
            dbms_output.put_line(to_char(to_date(fromdate,'yyyy-mm-dd'),'yyyy-mm-dd') || '~' || to_char(to_date(l_getdate,'yyyy-mm-dd')-1,'yyyy-mm-dd'));--需要插入到表中...
          end if;
          end if;
    end loop;
  end if;

  l_tmpdate1 := l_getdate;
  while to_date(l_tmpdate1,'yyyy-mm-dd')+14 <= to_date(todate,'yyyy-mm-dd') loop --排除结束日期所在周和前一周
    l_tmpdate1 := to_char(to_date(l_getdate,'yyyy-mm-dd')+6,'yyyy-mm-dd');--一周结束日期=一周开始日期+6
    dbms_output.put_line(l_getdate || '~' || l_tmpdate1);--需要插入到表中
    l_getdate := to_char(to_date(l_tmpdate1,'yyyy-mm-dd')+1,'yyyy-mm-dd');--一周开始日期=一周结束日期+1
  end loop;

  v_i := to_date(todate,'yyyy-mm-dd')-to_date(l_tmpdate1,'yyyy-mm-dd');
  --dbms_output.put_line('最后两周的天数:' || v_i);
  if v_i = 14 then
    dbms_output.put_line(to_char(to_date(l_tmpdate1,'yyyy-mm-dd')+1,'yyyy-mm-dd') || '~' || to_char(to_date(l_tmpdate1,'yyyy-mm-dd')+7,'yyyy-mm-dd'));
    dbms_output.put_line(to_char(to_date(l_tmpdate1,'yyyy-mm-dd')+8,'yyyy-mm-dd') || '~' || to_char(to_date(l_tmpdate1,'yyyy-mm-dd')+14,'yyyy-mm-dd'));
  else if v_i <= 10 then
    dbms_output.put_line(to_char(to_date(l_tmpdate1,'yyyy-mm-dd')+1,'yyyy-mm-dd') || '~' || to_char(to_date(todate,'yyyy-mm-dd'),'yyyy-mm-dd'));
  else if v_i > 10 and v_i < 14 then
    dbms_output.put_line(to_char(to_date(l_tmpdate1,'yyyy-mm-dd')+1,'yyyy-mm-dd') || '~' || to_char(to_date(l_tmpdate1,'yyyy-mm-dd')+7,'yyyy-mm-dd'));
    dbms_output.put_line(to_char(to_date(l_tmpdate1,'yyyy-mm-dd')+8,'yyyy-mm-dd') || '~' || to_char(to_date(todate,'yyyy-mm-dd'),'yyyy-mm-dd'));
  end if;
  end if;
  end if;
 
  dbms_output.put_line('=================打印月份====================');
  l_tmpdate1:=fromdate;
  WHILE (to_date(l_tmpdate1,'YYYY-MM-DD')-(to_date(todate,'YYYY-MM-DD'))) <= 0  LOOP
     DBMS_OUTPUT.PUT_LINE( l_tmpdate1 || '~' || l_tmplastdate);
     --计算下个月时间
     l_tmpdate1 := to_char(to_date(l_tmplastdate,'YYYY-MM-DD')+1,'YYYY-MM-DD');
     l_tmplastdate:= to_char(LAST_DAY(to_date(l_tmpdate1,'YYYY-MM-DD')),'YYYY-MM-DD');
  END LOOP;

END  printWeekAndMonth;

 

运行示例:


begin
  -- Call the procedure
  printweekandmonth(fromdate => '2012-01-01',
                    todate => '2012-12-31');
end;

=================打印周次====================
2012-01-01~2012-01-08
2012-01-09~2012-01-15
2012-01-16~2012-01-22
2012-01-23~2012-01-29
2012-01-30~2012-02-05
2012-02-06~2012-02-12
2012-02-13~2012-02-19
2012-02-20~2012-02-26
2012-02-27~2012-03-04
2012-03-05~2012-03-11
2012-03-12~2012-03-18
2012-03-19~2012-03-25
2012-03-26~2012-04-01
2012-04-02~2012-04-08
2012-04-09~2012-04-15
2012-04-16~2012-04-22
2012-04-23~2012-04-29
2012-04-30~2012-05-06
2012-05-07~2012-05-13
2012-05-14~2012-05-20
2012-05-21~2012-05-27
2012-05-28~2012-06-03
2012-06-04~2012-06-10
2012-06-11~2012-06-17
2012-06-18~2012-06-24
2012-06-25~2012-07-01
2012-07-02~2012-07-08
2012-07-09~2012-07-15
2012-07-16~2012-07-22
2012-07-23~2012-07-29
2012-07-30~2012-08-05
2012-08-06~2012-08-12
2012-08-13~2012-08-19
2012-08-20~2012-08-26
2012-08-27~2012-09-02
2012-09-03~2012-09-09
2012-09-10~2012-09-16
2012-09-17~2012-09-23
2012-09-24~2012-09-30
2012-10-01~2012-10-07
2012-10-08~2012-10-14
2012-10-15~2012-10-21
2012-10-22~2012-10-28
2012-10-29~2012-11-04
2012-11-05~2012-11-11
2012-11-12~2012-11-18
2012-11-19~2012-11-25
2012-11-26~2012-12-02
2012-12-03~2012-12-09
2012-12-10~2012-12-16
2012-12-17~2012-12-23
2012-12-24~2012-12-31
=================打印月份====================
2012-01-01~2012-01-31
2012-02-01~2012-02-29
2012-03-01~2012-03-31
2012-04-01~2012-04-30
2012-05-01~2012-05-31
2012-06-01~2012-06-30
2012-07-01~2012-07-31
2012-08-01~2012-08-31
2012-09-01~2012-09-30
2012-10-01~2012-10-31
2012-11-01~2012-11-30
2012-12-01~2012-12-31

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值