Oracle 计算工时除去节假日(返回小时数)

摘要:
--前提条件:DIM_oa_TIME包含每天,is_Work=1个工作日=0个非工作日--请参见:https://www.cnblogs.com/xiaobaidejiucuoben/p/14630923.htmlcreateorreplacefunctiongetworktime(开始日期,结束日期)返回编号为v_开始日期
--前提条件:DIM_oa_TIME 包含每一天,并且is_work=1 工作日 =0 非工作日 
--详见:https://www.cnblogs.com/xiaobaidejiucuoben/p/14630923.html

create or replace function getworktime(begindate in date,enddate in date) return number as
  v_begindate date;
  v_enddate date;
  v_nextdate date;--下一天0时
  v_date date;--当天0时
  beforeworkhournum number(10,2);--开始时间育当天24点两时间相差几个小时
  endworkhournum number(10,2);--结束时间与当天0点两时间相差几个小时
  workhournum number(10,2);--两时间相差几个小时
  workdaynum number(10,2);--两时间相差几个整天工作日
  daynum number(10,2);--两时间相差几个整天
  is_work int;--是否为非工作日
begin

    v_begindate :=begindate;
    v_enddate :=enddate;
    v_nextdate :=To_date(To_char(Trunc(v_begindate+1), 'yyyy/mm/dd hh24:mi:ss'), 'yyyy/mm/dd hh24:mi:ss');-- 开始日期的下一天0时
    v_date :=To_date(To_char(Trunc(v_enddate), 'yyyy/mm/dd hh24:mi:ss'), 'yyyy/mm/dd hh24:mi:ss');-- 结束日期的当天0时
    beforeworkhournum :=0;
    endworkhournum :=0;
    workhournum :=0;
    workdaynum :=0;
    daynum :=0;

    if v_begindate is null or v_enddate is null or v_begindate>v_enddate --开始日期大于结束日期时
    then
        workhournum :=0;
    else
        if to_number(To_date(To_char(v_begindate, 'yyyy/mm/dd'), 'yyyy/mm/dd hh24:mi:ss')-To_date(To_char(v_enddate, 'yyyy/mm/dd'), 'yyyy/mm/dd hh24:mi:ss'))=0 --开始日期和结束日期时为同一天
        then
            select  count(*) into is_work from DIM_oa_TIME where fdate=To_date(To_char(v_begindate, 'yyyy/mm/dd'), 'yyyy/mm/dd hh24:mi:ss') and is_work =1; --这天是否节假日
            if is_work=0 --or v_begindate is null or v_enddate is null 
            then
                workhournum :=0;
            else
                workhournum := round(to_number(v_enddate-v_begindate)*24,2);
            end if;  
        else 

            select  count(*) into is_work from DIM_oa_TIME where fdate=To_date(To_char(v_begindate, 'yyyy/mm/dd'), 'yyyy/mm/dd hh24:mi:ss') and is_work =1; --开始日期是否节假日
            if is_work=0 --or v_begindate is null
            then
                beforeworkhournum :=0;
            else
                beforeworkhournum :=round(to_number(v_nextdate-v_begindate)*24,2)+beforeworkhournum;-- 开始时间到下一天0时的小时数
            end if; 

            select count(*) into workdaynum from DIM_oa_TIME where fdate>=v_begindate and fdate<=v_enddate and is_work=1; --工作日相差天数
            select  count(*) into is_work from DIM_oa_TIME where fdate=To_date(To_char(v_enddate, 'yyyy/mm/dd'), 'yyyy/mm/dd hh24:mi:ss') and is_work =1; --结束日期是否节假日 
            if is_work=0 --or v_begindate is null
            then
                --如果v_enddate为节假日workdaynum不减1
                endworkhournum :=0;
            else
                endworkhournum :=round(to_number(v_enddate-v_date)*24,2)+endworkhournum;-- 下一天0时到结束时间的小时数
                workdaynum :=workdaynum-1;--如果v_enddate不为节假日workdaynum减1
            end if;  
            -- daynum :=to_date(To_char(v_enddate, 'yyyy/mm/dd'),'yyyy/mm/dd') - to_date(To_char(v_begindate, 'yyyy/mm/dd'),'yyyy/mm/dd'); --工作日相差天数            
        end if;    
    end if;
    workhournum:=workdaynum*24+endworkhournum+beforeworkhournum+workhournum;
    return workhournum;
end;

---select getworktime(to_date('2021-04-01 11:12:38','yyyy-mm-dd hh24:mi:ss'),to_date('2021-04-03 11:12:38','yyyy-mm-dd hh24:mi:ss')) from  dual;

--select case when (count(*)-1)<0 then 0 else (count(*)-1) end from DIM_oa_TIME where fdate>=to_date('2020-01-15 15:23:58','yyyy-mm-dd hh24:mi:ss') and fdate<=to_date('2020-01-16 17:57:48','yyyy-mm-dd hh24:mi:ss') and is_work=1

--select (count(*)-2) from DIM_oa_TIME  where fdate>=to_date('2020-01-15 15:23:58','yyyy-mm-dd hh24:mi:ss') and fdate<=to_date('2020-01-16 17:57:48','yyyy-mm-dd hh24:mi:ss') and is_work=1

--select  count(*) into is_work from DIM_oa_TIME where fdate=to_date('2021-04-03 02:00:00','yyyy-mm-dd hh24:mi:ss') and is_work =1

-- select round(to_number(to_date('2020-01-16 00:00:00','yyyy-mm-dd hh24:mi:ss')-to_date('2020-01-15 15:23:58','yyyy-mm-dd hh24:mi:ss'))*24,2) from dual

-- select round(to_number(to_date('2020-01-16 17:57:48','yyyy-mm-dd hh24:mi:ss')-to_date('2020-01-16 00:00:00','yyyy-mm-dd hh24:mi:ss'))*24,2) from dual
-- select to_number(to_date('2020-01-16 17:57:48','yyyy-mm-dd hh24:mi:ss')-to_date('2020-01-16 00:00:00','yyyy-mm-dd hh24:mi:ss'))*24 from dual

-- select round(to_date('2020-01-16 17:57:48','yyyy-mm-dd hh24:mi:ss')-to_date('2020-01-15 15:23:58','yyyy-mm-dd hh24:mi:ss'),2) from dual
--select  To_date(To_char(Trunc(to_date('2020-01-16 17:57:48','yyyy-mm-dd hh24:mi:ss')), 'yyyy/mm/dd hh24:mi:ss'), 'yyyy/mm/dd hh24:mi:ss')  from dual

免责声明:文章转载自《Oracle 计算工时除去节假日(返回小时数)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇开发人员常用的10个Sublime Text插件简单验证码识别程序(源码)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

【转】android电池(四):电池 电量计(MAX17040)驱动分析篇

关键词:android 电池  电量计  MAX17040 任务初始化宏 power_supply 平台信息:内核:linux2.6/linux3.0系统:android/android4.0 平台:samsung exynos 4210、exynos 4412 、exynos 5250 作者:xubin341719(欢迎转载,请注明作者) 欢迎指正错误...

libpcap编程实例

1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pcap.h> 4 #include <errno.h> 5 #include <sys/socket.h> 6 #include <netinet/in...

穿透代理服务器编程

正文   在网络程序设计过程中,我们经常要与各种类型的代理服务器打交道,比如在企业内部网通过代理去访问Internet网上的服务器等等,一般代理服务器支持几种常见的代理协议标准,如Socks4,Socks5,Http代理,其中Socks5需要用户验证,代理相对复杂。我在查阅RFC文档和相关资料后,特总结一些TCP协议穿透代理服务器的程序片断,希望对大家...

ip黑白名单防火墙frdev的原理与实现

汤之盘铭曰 苟日新 日日新 又日新 康诰曰 作新民 诗曰 周虽旧邦 其命维新 是故 君子无所不用其极                           ——礼记·大学 在上一篇文章《DDoS攻防战 (二) :CC攻击工具实现与防御理论》中,笔者阐述了一个防御状态机,它可用来抵御来自应用层的DDoS攻击,但是该状态机依赖一个能应对大量条目快速增删的ip黑白...

python 获取系统时间,新建时间目录

import datetime import os theTime = datetime.datetime.now() print(theTime) theTime = str(theTime) date_split = theTime.strip().split(' ') date_today = date_split[0].replace('-', '...

Nodejs事件引擎libuv源码剖析之:高效线程池(threadpool)的实现

     声明:本文为原创博文,转载请注明出处。      Nodejs编程是全异步的,这就意味着我们不必每次都阻塞等待该次操作的结果,而事件完成(就绪)时会主动回调通知我们。在网络编程中,一般都是基于Reactor线程模型的变种,无论其怎么演化,其核心组件都包含了Reactor实例(提供事件注册、注销、通知功能)、多路复用器(由操作系统提供,比如kque...