函数设计思路是:
首先判断哪些假期会在我操作的时间内:
这样的假期必须满足:假期的开始时间比我操作结束时间要早,而且假期的结束时间比我操作开始时间要迟。
在去判断假期里面是否需要修改我操作的开始时间和操作的结束时间(因为此时我只关注是一个时间段)
如果假期的开始时间早于我操作的开始时间,则修改我操作的开始为假期的操作开始时间。
如果假期的结束时间晚于我操作的结束时间,则修改我操作的结束时间的假期的操作时间。(实际实现的时候用的假期的开始时间,只是少加了一个事件跨度,效果一样)
在看我操作期间的跨度了。如果我修改之后的操作开始时间早于一个假期的开始时间,而且我修改之后的结束时间迟于假期结束的时间,则着整个假期,我都得减掉。
我现在这样设计的:
假期表有三个主要的字段:
假期开始时间点,假期结束时间点,假期历时时间段。(整个表示都用整形秒来表示,以为系统时间都是整形秒的格式)
表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;