遇到一个需求,需要计算投诉发生后是否在某个时间段中处理完这个投诉,并且时间段用的是工作时间。
CREATE OR REPLACE FUNCTION "F_OVERTIME" (
p_dayBegin in date,
p_dayEnd in date,
p_num in number,
p_code in varchar2)
/************************************************************/
/* funcate : F_OVERTIME
/* Description : 计算工作小时数
: 工作日:早8:00~晚20:00 共计12小时
新疆西藏顺延两个小时
: 推算公式: 时间差 - 12*相差天数
时间差 = (结束时间-开始时间)
/* Parameters : p_dayBegin 开始时间
p_dayEnd 结束时间
p_num 保留位数
p_code 省份代码
*/
return number
is
d_dayBegin date := p_dayBegin; --派单时间
d_dayEnd date := p_dayEnd; --当前时间
v_dayBegin date; --处理后的派单时间
v_dayEnd date; --处理后的当前时间
v_num number := p_num; --小数保留位数
v_code varchar(5) := p_code; --省份code
v_workBegin number :=1; --开始工作时间
v_workEnd number :=1; --结束工作时间
v_calcHour number; --总相差小时数
v_calcDay number; --相差天数
v_hour number; --实际相差小时数
begin
--判断省份,计算工作时间
if v_code not in ('xj','xz') then --非新疆西藏的工作时间
v_workBegin := 8 / 24;
v_workEnd := 20 / 24;
else --新疆西藏的工作时间
v_workBegin := 10 / 24;
v_workEnd := 22 / 24;
end if;
--进行判断处理派单时间
if d_dayBegin > (TRUNC(d_dayBegin) + v_workEnd) THEN --晚上工作时间以后
v_dayBegin :=(TRUNC(d_dayBegin) + v_workEnd); --变成当天晚上工作时间
elsif d_dayBegin < (TRUNC(d_dayBegin) + v_workBegin) THEN --早上工作时间之前
v_dayBegin :=(TRUNC(d_dayBegin) + v_workBegin); --变成当天早上工作时间
else
v_dayBegin := d_dayBegin; --工作时间
end if;
--进行判断处理当前时间
if d_dayEnd > (TRUNC(d_dayEnd) + v_workEnd) THEN --晚上工作时间之后
v_dayEnd :=(TRUNC(d_dayEnd) + v_workEnd); --变成当天晚上工作时间
elsif d_dayEnd < (TRUNC(d_dayEnd) + v_workBegin) THEN --早上工作时间之前
v_dayEnd :=(TRUNC(d_dayEnd) + v_workBegin); --变成当天早上工作时间
else
v_dayEnd := d_dayEnd; --工作时间
end if;
--计算时间差
v_calcHour := to_number(v_dayend - v_daybegin) * 24;
--计算相差天数
v_calcDay := to_number(trunc(v_dayend) - trunc(v_daybegin));
--计算工作小时数
v_hour := round(v_calcHour - 12 * v_calcDay,v_num);
return v_hour;
end F_OVERTIME;