Für eine Feiertagsermittlung ist nun einmal der Ostersonntag das Um und Auf. Doch wie kommt man auf den?

Wikipedia schreibt dazu:

Das Osterdatum ist das Datum für den Ostersonntag im christlichen Jahreskreis. Auf Grund neutestamentlicher Überlieferung wurde der Ostertermin festgelegt als der erste Sonntag nach dem Frühlingsvollmond. Vereinbartes Datum für den frühesten Frühlingsvollmond ist der 21. März, so dass der früheste Ostersonntag auf den 22. März fällt. Spätestes Osterdatum ist der 25. April.
Quelle: http://de.wikipedia.org/wiki/Osterdatum

Ok, das hilft nicht viel, wenn man nicht weiß, wie man den Frühlingsvollmond berechnet. - Braucht man aber nicht, denn es gibt von Gauß hat 1816 eine Formel aufgestellt, welche recht einfach den Ostertermin bestimmt (leider gibt es ein paar Ausnahmen, welche er zwar benannt hat, aber nicht in die Formel einpflegte [Anmerkung: so wie ich es verstanden hab]). Doch ein Herr Lichtenberg hat dann 1997 die Formel dahingegend adaptiert, die da lautet:

1. die Säkularzahl:

K(X) = X div 100

2. die säkulare Mondschaltung

M(K) = 15 + (3K + 3) div 4 - (8K + 13) div 25

3. die säkulare Sonnenschaltung

S(K) = 2 - (3K + 3) div 4

4. den Mondparameter

A(X) = X mod 19

5. den Keim für den ersten Vollmond im Frühling

D(A,M) = (19A + M) mod 30

6. die kalendarische Korrekturgröße

R(D,A) = D div 29 + (D div 28 - D div 29) (A div 11)

7. die Ostergrenze

OG(D,R) = 21 + D - R

8. den ersten Sonntag im März

SZ(x,S) = 7 - (X + X div 4 + S) mod 7

9. die Entfernung des Ostersonntags  von der Ostergrenze (Osterentfernung in Tagen)

OE(OG,SZ) = 7 - (OG - SZ) mod 7

10. das Datum des Ostersonntags als Märzdatum (32. März = 1. April usw.)

OS = OG + OE

Soviel zur Theorie. [Anmerkung: wichtig ist, immer in ganzen Zahlen zu rechnen - INT]
... und daraus entsteht dann folgende SVF bzw. TVF

create function dbo.TVF_Ostersonntag (@datum as date)
returns table
as
return
(
select case when OS < 32
            then cast (right('000' + cast (X as varchar(4),4) + '-03-' + right('0'+cast (OS as varchar(2)),2) as date)
            else cast (right('000' + cast (X as varchar(4)),4) + '-04-' + right('0'+cast (OS-31 as varchar(2)),2) as date)
       end Ostersonntag
from (
  select  OS = OG + OE
         ,X
  from (
    select  OE = cast (7 - (OG-SZ) % 7 as int)
           ,X
           ,OG
    from (
      select  SZ = cast (7 - (X + X / 4 + S) % 7 as int)
             ,X
             ,OG = cast (21 + D -R as int)
      from (
        select  R = cast (D / 29 + (D / 28 - D / 29) * (A / 11) as int)
               ,X
               ,S
               ,D
        from (
          select  D = cast ((19*A + M) % 30 as int)
                 ,X
                 ,S
                 ,A
          from (
            select  A= cast (X % 19 as int)
                   ,S= cast (2 - (3 * K + 3) / 4 as int)
                   ,M= cast (15 + (3 * K + 3) / 4 - (8 * K + 13) / 25 as int)
                   ,X
            from (
              select  K = cast (X/100 as int)
                     ,X
              from (
                select  cast (year (@datum) as int) X
                   ) a
                 ) a
               ) a
             ) a
           ) a
         ) a
       ) a
     ) a
)
GO

und das Ganze noch als Scalar Valued Function:

CREATE FUNCTION [dbo].[SVF_Ostersonntag](@datum as date)RETURNS date
AS
BEGIN
  declare @Ostersonntag date
 
  declare @A int , @K int , @M int , @D int , @S int , @R int , @OG int , @SZ int , @OE int , @OS int
  declare @X int
  set @X = cast (year (@datum) as int)


  set @K = @X/100
  set @M = 15 + (3 * @K + 3) / 4 - (8 * @K + 13) / 25
  set @S = 2 - (3 * @K + 3) / 4
  set @A = @X % 19
  set @D = (19 * @A + @M) % 30
  set @R = @D / 29 + (@D / 28 - @D / 29)*(@A / 11)
  set @OG = 21 + @D - @R
  set @SZ = 7 - (@X + @X / 4 + @S) % 7
  set @OE = 7 - (@OG - @SZ) % 7
  set @OS = (@OG + @OE)


  if @OS < 32
  begin
    set @Ostersonntag = right('000' + cast (@X as varchar(4)),4) + '-03-' + right('0'+cast (@OS as varchar(2)),2)
  end
  else begin
    set @OS = @OS - 31 
    set @Ostersonntag = right('000' + cast (@X as varchar(4)),4) + '-04-' + right('0'+cast (@OS as varchar(2)),2)
  end


  return (@Ostersonntag)
end
GO

Wen es jetzt interessiert, warum ich eine TVF und eine SVF gemacht hab, hier kannst du genaueres darüber erfahren.