常用函数--不同时间粒度循环取数之sp_Utl_ComboTime

CREATE OR REPLACE FUNCTION sp_Utl_ComboTime(
    iTime            DATE,          -- 输入时间
    iAdmBeginTime DATE,         -- 输入偏移开始时间
    iAdmEndTime     DATE,       -- 输入偏移结束时间
    iTimeSectFlag INTEGER,    -- 步长
    iComboFlag       INTEGER, -- 偏移标志, 0: 加偏移开始时间; 非0: 加偏移结束时间
    oTime OUT     DATE           -- 输出时间
) RETURN INTEGER
AS
    tTime         VARCHAR2(50);   -- 工作时间
    v_ErrM        VARCHAR2(200);
BEGIN
    -- 判断TimeStatFlag, 为tTime赋值


    -- 时段: 步长为小时
    IF iTimeSectFlag = 1 THEN
        tTime := TO_CHAR(iTime, 'YYYY-MM-DD HH24:MI:SS');
    END IF;


    -- 小时: 步长为小时
    IF iTimeSectFlag = 2 THEN
        tTime := TO_CHAR(iTime, 'YYYY-MM-DD HH24:')||'00:00';
    END IF;




    -- 半小时: 步长为半小时不用处理时间
    -- format的时候已经搞定了
    IF iTimeSectFlag = 10 THEN
        tTime := TO_CHAR(iTime, 'YYYY-MM-DD HH24:MI:SS');
    END IF;


    -- 天: 步长为天, 偏移为小时
    IF iTimeSectFlag = 3 THEN
        IF iComboFlag = 0 THEN
            tTime := TO_CHAR(iTime, 'YYYY-MM-DD')||' '||TO_CHAR(iAdmBeginTime, 'HH24:MI:SS');
        ELSE
            IF iAdmBeginTime >= iAdmEndTime THEN
                tTime := TO_CHAR(iTime + 1, 'YYYY-MM-DD')||' '||TO_CHAR(iAdmEndTime, 'HH24:MI:SS');
            ELSE
                tTime := TO_CHAR(iTime, 'YYYY-MM-DD')||' '|| TO_CHAR(iAdmEndTime, 'HH24:MI:SS');
            END IF;
        END IF;
    END IF;


    -- 周: 步长为周, 步长为1天, 范围为iTime到周日起始、结束时间已经在sp_Utl_FormatTime中修正,
    -- 在此不需要做任何处理。
    IF iTimeSectFlag = 4 THEN
        tTime := TO_CHAR(iTime, 'YYYY-MM-DD HH24:MI:SS');
    END IF;


    -- 月: 步长为月, 偏移为天
    IF iTimeSectFlag = 6 THEN
        IF iComboFlag = 0 THEN
            tTime := TO_CHAR(iTime, 'YYYY-MM-')||TO_CHAR(iAdmBeginTime, 'DD HH24:MI:SS');
        ELSE
            IF iAdmBeginTime >= iAdmEndTime THEN
                tTime := TO_CHAR(ADD_MONTHS(iTime, 1), 'YYYY-MM-')||TO_CHAR(iAdmEndTime, 'DD HH24:MI:SS');
            ELSE
                tTime := TO_CHAR(iTime,'YYYY-MM-')||TO_CHAR(iAdmEndTime, 'DD HH24:MI:SS');
            END IF;
        END IF;
    END IF;


    -- 统计步长为季度
    IF iTimeSectFlag = 7 THEN
        DECLARE
            cStep CONSTANT   INTEGER := 3;
            tMonthTime       INTEGER;
            tMonthAdm        INTEGER;
            tStep            INTEGER;
            tMonth           CHAR(2);
            tAdmBeginTime    DATE;
            tAdmEndTime      DATE;
        BEGIN
            tAdmBeginTime := iAdmBeginTime;
            tAdmEndTime := iAdmEndTime;
            tMonth := TO_NUMBER(TO_CHAR(iTime, 'MM'));


            --计算起始时间
            IF iComboFlag = 0 THEN
                tStep := ROUND((tMonth + 1) / cStep) - 1;
                tMonthAdm := TO_NUMBER(TO_CHAR(tAdmBeginTime, 'MM'));
                tMonth := tStep * cStep + tMonthAdm;
                tTime := TO_CHAR(iTime, 'YYYY-') || '01' || TO_CHAR(tAdmBeginTime, '-DD HH24:MI:SS');
            ELSE  --计算结束时间
                IF (iAdmBeginTime < iAdmEndTime) THEN
                    tStep := ROUND((tMonth + 1) / cStep) - 1;
                    tMonthAdm := TO_NUMBER(TO_CHAR(tAdmEndTime, 'MM'));
                    tMonth := tStep * cStep + tMonthAdm;
                ELSE
                    tStep := ROUND((tMonth + 1) / cStep) - 1;
                    tMonthAdm := TO_NUMBER(TO_CHAR(tAdmEndTime, 'MM')) + cStep;
                    tMonth := tStep * cStep + tMonthAdm;
                END IF;
                tTime := TO_CHAR(iTime, 'YYYY-') || '01' || TO_CHAR(tAdmEndTime, '-DD HH24:MI:SS');
            END IF;
            tTime := TO_CHAR(ADD_MONTHS(TO_DATE(tTime, 'YYYY-MM-DD HH24:MI:SS'), tMonth - 1), 'YYYY-MM-DD HH24:MI:SS');
        END;
    END IF;


    -- 统计步长为半年
    IF iTimeSectFlag = 8 THEN
        DECLARE
            cStep CONSTANT   INTEGER := 6;
            tMonthTime       INTEGER;
            tMonthAdm        INTEGER;
            tStep            INTEGER;
            tMonth           CHAR(2);
            tAdmBeginTime    DATE;
            tAdmEndTime      DATE;
        BEGIN
            tAdmBeginTime := iAdmBeginTime;
            tAdmEndTime := iAdmEndTime;
            tMonth := TO_NUMBER(TO_CHAR(iTime, 'MM'));


            --计算起始时间
            IF iComboFlag = 0 THEN
                tStep := ROUND((tMonth + 2) / cStep) - 1;
                tMonthAdm := TO_NUMBER(TO_CHAR(tAdmBeginTime, 'MM'));
                tMonth := tStep * cStep + tMonthAdm;
                tTime := TO_CHAR(iTime, 'YYYY-') || '01' || TO_CHAR(tAdmBeginTime, '-DD HH24:MI:SS');
            ELSE  --计算结束时间
                IF (iAdmBeginTime < iAdmEndTime) THEN
                    tStep := ROUND((tMonth + 2) / cStep) - 1;
                    tMonthAdm := TO_NUMBER(TO_CHAR(tAdmEndTime, 'MM'));
                    tMonth := tStep * cStep + tMonthAdm;
                ELSE
                    tStep := ROUND((tMonth + 2) / cStep) - 1;
                    tMonthAdm := TO_NUMBER(TO_CHAR(tAdmEndTime, 'MM')) + cStep;
                    tMonth := tStep * cStep + tMonthAdm;
                END IF;
                tTime := TO_CHAR(iTime, 'YYYY-') || '01' || TO_CHAR(tAdmEndTime, '-DD HH24:MI:SS');
            END IF;
            tTime := TO_CHAR(ADD_MONTHS(TO_DATE(tTime, 'YYYY-MM-DD HH24:MI:SS'), tMonth - 1), 'YYYY-MM-DD HH24:MI:SS');
        END;
    END IF;


    -- 统计步长为年
    IF iTimeSectFlag = 9 THEN
        IF iComboFlag = 0 THEN
            tTime := TO_CHAR(iTime, 'YYYY-')||TO_CHAR(iAdmBeginTime, 'MM-DD HH24:MI:SS');
        ELSE
            IF iAdmBeginTime >= iAdmEndTime THEN
                tTime := TO_CHAR(ADD_MONTHS(iTime, 12), 'YYYY-')|| TO_CHAR(iAdmEndTime, 'MM-DD HH24:MI:SS');
            ELSE
                tTime := TO_CHAR(iTime, 'YYYY-')||TO_CHAR(iAdmEndTime, 'MM-DD HH24:MI:SS');
            END IF;
        END IF;
    END IF;


    -- 统计步长为旬
    IF iTimeSectFlag = 5 THEN
        IF iComboFlag = 0 THEN
            IF TO_NUMBER(TO_CHAR(iTime,'DD')) <= 10 THEN
               tTime := TO_CHAR(iTime,'YYYY-MM-') || '01 00:00:00';
            ELSIF TO_NUMBER(TO_CHAR(iTime,'DD')) <= 20 THEN
               tTime := TO_CHAR(iTime,'YYYY-MM-') || '11 00:00:00';
            ELSE
               tTime := TO_CHAR(iTime,'YYYY-MM-') || '21 00:00:00';
            END IF;
        ELSE
            IF TO_NUMBER(TO_CHAR(iTime,'DD')) < 10 THEN
               tTime := TO_CHAR(iTime,'YYYY-MM-') || '01 00:00:00';
            ELSIF TO_NUMBER(TO_CHAR(iTime,'DD')) < 20 THEN
               tTime := TO_CHAR(iTime,'YYYY-MM-') || '11 00:00:00';
            ELSIF TO_NUMBER(TO_CHAR(iTime,'DD')) < 30 THEN
               tTime := TO_CHAR(iTime,'YYYY-MM-') || '21 00:00:00';
            ELSE
               tTime := TO_CHAR(ADD_MONTHS(iTime,1),'YYYY-MM-') || '01 00:00:00';
            END IF;
        END IF;
    END IF;






    oTime := TO_DATE(tTime, 'YYYY-MM-DD HH24:MI:SS');


    RETURN 0;


EXCEPTION
    WHEN OTHERS THEN
        v_ErrM := SUBSTR(SQLERRM, 1, 200);
        DBMS_OUTPUT.PUT_LINE(v_ErrM);
        RETURN 1;
END sp_Utl_ComboTime;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

科技改变未来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值