oracleplsqloracle-sqldeveloperplsqldeveloperoraclereports

count Sunday in plsql between two dates :date1 and :date2


I know there is lot of work for this on forums but i tried many things but get error please I have two parameters in oracle reports :date1 and :date2 I want to check sunday and then return gives me how many Sundays in these two dates

function SUNDAY_CFormula return NUMBER is
start_date DATE := :DATE1;
end_date DATE := :DATE2;
A NUMBER;
begin
SELECT Count(*) 
FROM   (SELECT To_char(start_date + ( LEVEL - 1 ), 'fmday')INTO A 
        FROM DUAL;   
        CONNECT BY LEVEL <= end_date - start_date + 1) 
WHERE  A IN ( 'sunday' );
RETURN A;
end;

Solution

  • You could rewrite your function like below. It is safer to add 'nls_date_language = english' clause in your to_char function in order to make your function independent from your default environnment settings.

    create or replace 
    function SUNDAY_CFormula (DATE1 date, DATE2 date) return NUMBER is
    start_date DATE := DATE1;
    end_date DATE := DATE2;
    A NUMBER;
    begin
    SELECT Count(*) INTO A
    FROM   (
           SELECT To_char(start_date + ( LEVEL - 1 ), 'fmday', 'nls_date_language = english') A
            FROM DUAL 
            CONNECT BY LEVEL <= end_date - start_date + 1
            ) t
    WHERE  t.A IN ( 'sunday' );
    RETURN A;
    end;
    /
    

    You could even use below version to make your function more flexible about the two dates it takes as parameters, no matter if date1 is greater or less than date2.

    create or replace 
    function SUNDAY_CFormula (DATE1 date, DATE2 date) return NUMBER is
    start_date DATE := DATE1;
    end_date DATE := DATE2;
    A NUMBER;
    begin
    SELECT Count(*) INTO A
    FROM   (SELECT To_char(start_date + ( LEVEL - 1 ), 'fmday', 'nls_date_language = english') A
            FROM DUAL 
            CONNECT BY LEVEL <= greatest(end_date, start_date) - least(end_date, start_date) + 1
            ) t
    WHERE  t.A IN ( 'sunday' );
    RETURN A;
    end;
    /