前面发过一个帖子。见:Oracle 过滤法定假期
  在此基础上在问一个问题。
  假期表做好之后,要过滤时间段里面的假期,可不是一件容易的事情。有没有还得算法,大家说说!谢谢!

解决方案 »

  1.   

    那主要看你的假期表的设计叻,假期表可以用start, end,也可以start,duration,或者duration都是1, 每个连续的假期是多个记录。或者是加上type,混合设计。根据你的假期表的设计来选择叻。 也可以使用function封装假期计算的方式。
      

  2.   


    我现在这样设计的:
    假期表有三个主要的字段:
    假期开始时间点,假期结束时间点,假期历时时间段。(整个表示都用整形秒来表示,以为系统时间都是整形秒的格式)
    表week_day 
    create table WEEK_DAY
    (
      HID     NUMBER,            --id
      D_BEGIN DATE,              --假期开始日期格式
      D_END   DATE,              --假期结束日期格式
      H_DESC  NVARCHAR2(100),    --假期名称
      N_BEGIN NUMBER,            --假期开始整形秒格式
      N_END   NUMBER,            --假期结束整形秒格式
      SECS    NUMBER             --假期长度
    )假期开始时间     假期结束时间     假期开始整形秒格式 假期结束整形秒格式 假期长度
    2007-1-6 2007-1-8 1168012800 1168185600 172800
    2007-1-13 2007-1-15 1168617600 1168790400 172800
    2007-1-20 2007-1-22 1169222400 1169395200 172800
    2007-1-27 2007-1-29 1169827200 1170000000 172800
    2007-2-3 2007-2-5 1170432000 1170604800 172800
    2007-2-10 2007-2-12 1171036800 1171209600 172800
    2007-2-17 2007-2-19 1171641600 1171814400 172800
    2007-2-24 2007-2-26 1172246400 1172419200 172800
    2007-3-3 2007-3-5 1172851200 1173024000 172800
    2007-3-10 2007-3-12 1173456000 1173628800 172800
    2007-3-17 2007-3-19 1174060800 1174233600 172800
    2007-3-24 2007-3-26 1174665600 1174838400 172800过滤假期是通过函数去过滤的。
    create or replace function get_diff(iBegin number,iEnd number)
    --iBegin 操作开始时间  iEnd 操作结束时间
    return number
    as
      args_begin number ;--存储 iBegin 临近的假期开始时间
      args_end number ; --存储 iBegin 临近的假期开始时间
      nTbegin number ;--存储游标零时值 开始值
      nTend number;--存储游标零时值 结束值
      nNum number default 0; --存储操作期间块跨越的假期小时总数
      tNum number default 0; --存储操作期间块跨越的假期小时总数
      ret number default 0;
      t_week_day week_day%rowtype;  cursor c_week_day is select * from week_day where n_end>iBegin and n_begin<iEnd order by hid;begin
      args_begin :=iBegin;
      args_end :=iEnd;
      open c_week_day;
      loop
        fetch c_week_day into t_week_day;
        EXIT WHEN c_week_day%NOTFOUND;    nTbegin := t_week_day.n_begin ;
        nTend := t_week_day.n_end;
        tNum := t_week_day.secs;    if  iBegin > nTbegin and iBegin < nTend then
        --判断开始 求出确切的开始时间
         args_begin := nTbegin;
        end if ;    if iEnd < nTend and iEnd > nTbegin then
        --判断结束 求出确切的结束时间
        args_end := nTbegin;
        end if ;    if (( args_begin <= nTbegin) and ( nTend <= args_end)) then    --判断是否有中间点
        nNum := nNum + tNum;--注意修改为整形秒的结构
        ret := ret+1;
        end if ;    end loop;
      close c_week_day;
      dbms_output.put_line('判断开始 求出确切的开始时间??'||args_begin);
      dbms_output.put_line('判断开始 求出确切的结束时间??'||args_end);
      dbms_output.put_line('判断开始 求出确切的间隔假期段数??'||ret);
      dbms_output.put_line('判断开始 求出确切的间隔假期总数数??'||nNum);
     -- ret := args_begin - args_end - nNum;
    return ret;
    end get_diff;
      

  3.   

    每年的固定的节日也要这样处理么,我觉得可以针对mircosfot project工具里的worktime的做法,来做你的假期表,他的功能比较强大。