通过排除周末和自定义/业务特定假期,在开始日期和结束日期之间计算工作日(包括时间部分)

时间:2012-10-20 00:03:52

标签: oracle oracle10g oracle11g

你能不能帮我解决一下如何计算。在开始日期和结束日期之间的营业日,不包括周末和周末特定业务假期。假设我们将开始日期,结束日期和自定义假期表与下面提到的假日日期列表一起使用。

开始日期(mm / dd / yyyy hh24:mi:ss):'10 / 15/2012 08:00:00'

结束日期(mm / dd / yyyy hh24:mi:ss):'10 / 23/2012 10:30:00'

holiday_table.business_holiday_date值(mm / dd / yyyy)

2012年10月17日

2012年10月19日

2012年10月22日

需要通过考虑计算中日期的时间部分来计算工作日(因此可以预期工作日的分数以及例如1.25,3.7等)

感谢您能否尽快帮助我。

-James

2 个答案:

答案 0 :(得分:0)

尝试:

SELECT(end_date - start_date) - 
(select count(*) 
 from holiday_table 
 where business_holiday_date >= start_date
 and business_holiday_date <= end_date)
FROM dual

Here是一个小提琴

答案 1 :(得分:0)

我有一个只使用2个日期的功能,但你可以改进它。你去......

  1. 首先检查假期表中有多少天,不包括周末。
  2. 在两个日期之间获取工作日(MON到FRI),然后减去假期。

    create or replace
    FUNCTION calculate_business_days (p_start_date IN DATE, p_end_date IN DATE)
            RETURN NUMBER IS
            v_holidays     NUMBER;
            v_start_date   DATE   := TRUNC (p_start_date);
            v_end_date     DATE   := TRUNC (p_end_date);
            BEGIN
            IF v_end_date >= v_start_date
            THEN
                    SELECT COUNT (*)
                    INTO v_holidays
                    FROM holidays
                    WHERE day BETWEEN v_start_date AND v_end_date
                    AND day NOT IN (
                            SELECT hol.day 
                            FROM holidays hol 
                            WHERE MOD(TO_CHAR(hol.day, 'J'), 7) + 1 IN (6, 7)
                    );
    
            RETURN   GREATEST (NEXT_DAY (v_start_date, 'MON') - v_start_date - 2, 0)
                 +   (  (  NEXT_DAY (v_end_date, 'MON')
                         - NEXT_DAY (v_start_date, 'MON')
                        )
                      / 7
                     )
                   * 5
                 - GREATEST (NEXT_DAY (v_end_date, 'MON') - v_end_date - 3, 0)
                 - v_holidays;
            ELSE
                    RETURN NULL;
            END IF;
    END calculate_business_days;
    
  3. 之后你可以测试一下,如:

        select 
                calculate_business_days('21-AUG-2013','28-AUG-2013') as business_days 
        from dual;