Calculate holidays in SQL

To my surprise, it is actually possible to calculate holidays in SQL, because most of our holidays are at an offset to Easter Sunday.

The example below is based on the Netherlands, but can easily adapted to your locality.

For those of you who want a 7 KB console app to play around with, you can find that on my GitHub: https://github.com/ekelmans/BerekenFeestdagen

And for as long it is up you can also use my Azure Function on: https://isthisdateaholiday.azurewebsites.net/api/fnIsThisDateAHoliday?d=2021-12-25&code=tIsaPavueRYmTkBK7u58IwoAPRc2e9B7AcCcuUVcD0dXCgnCZHQeKA==

/***************************************************************************************
							tools.fnCalculateHolidays 
****************************************************************************************
Calculates Easter Sunday for a given year, the rest of the holidays can be calculated
as an offset to Easter Sunday using the paschal algorithm

Usage:
select * from tools.fnCalculateHolidays(2025)
****************************************************************************************
Versie		: 1.0
Datum		: 2021-05-12
Author		: Theo Ekelmans

Versie		: 1.1
Datum		: 2021-05-17
Author		: Theo Ekelmans
Change		: Goede vrijdag en Bevrijdingsdag geschrapt als vrije dagen.
--------------------------------------------------------------------------------------*/
ALTER FUNCTION [tools].[fnCalculateHolidays] 
(	
	@Y int
)
returns @list table (
	  [HolidayName] [varchar](50)
	, [HolidayDate] datetime
)
AS

begin
    declare @jaar varchar(4)

    set @jaar = cast(@Y as varchar(4))

    -- the paschal algorithm is only valid between 1901 and 2099
    if @jaar between 1901 and 2099
    begin
        -- vaste dagen
        declare @nieuwjaar as datetime 
        declare @bevrijdingsdag as datetime 
        declare @kerstmis as datetime 
        declare @tweedekerstdag as datetime 
        declare @koningsdag as datetime 
        declare @paasZondag as datetime 
        declare @paasmaandag as datetime 
        declare @goedevrijdag as datetime
        declare @hemelvaart as datetime
        declare @pinksteren as datetime
        declare @pinkstermaandag as datetime


        set @nieuwjaar = @jaar + '-01-01'
        set @bevrijdingsdag = @jaar + '-05-05'
        set @kerstmis = @jaar + '-12-25'
        set @tweedekerstdag = @jaar + '-12-26'
        set @koningsdag = @jaar + '-04-27'


        -- Als Koningsdag op zondag valt is het de dag ervoor
        if DATENAME(dw, @koningsdag) = 'Sunday'
        begin
            set @koningsdag = dateadd(day, -1, @koningsdag)
        end

        -- Reken paasZondag uit
        set @paasZondag = (select tools.fnCalculateEasterSunday(@Y));

        -- Reken de rest uit via een offset
        set @paasmaandag = dateadd(day, 1, @paasZondag); -- 1 dag na pasen
        set @goedevrijdag = dateadd(day, -2, @paasZondag); -- 2 dag voor pasen
        set @hemelvaart = dateadd(day, 39, @paasZondag); -- 39 dagen na pasen
        set @pinksteren = dateadd(day, 49, @paasZondag); -- 10 dagen na hemelvaart
        set @pinkstermaandag = dateadd(day, 50, @paasZondag); -- 1 dag na pinksteren

        insert into @list ([HolidayName], [HolidayDate])
	    values   ('Nieuwjaar' , @nieuwjaar)
                --,('Goede vrijdag' , @goedevrijdag)
                ,('Pasen' , @paasZondag)
                ,('Paasmaandag' , @paasmaandag)
                ,('Koningsdag' , @koningsdag)
                --,('Bevrijdingsdag' , @bevrijdingsdag)
                ,('Hemelvaart' , @hemelvaart)
                ,('Pinksteren' , @pinksteren)
                ,('Pinkstermaandag' , @pinkstermaandag)
                ,('Kerstmis' , @kerstmis)
                ,('2e Kerstdag' , @tweedekerstdag)

    end 
    
    return
end

Leave a Reply

Your email address will not be published. Required fields are marked *