Berechnung von Ostersonntag & Co bis 2100

Wie die meisten wissen, gibt es im Jahr Feiertage, die auf feste Termine fallen (z.B. Weihnachten) sowie Feiertage, die sich am Mondumlauf orientieren. Dabei ist der “Ankerpunkt” der Ostersonntag. Dieses Datum ist so festgelegt, dass es auf den ersten Sonntag nach dem ersten Vollmond im Frühling fällt (seit dem Konzil von Nicäa im Jahre 325 ist das so).

Quelle: Wikipedia

Somit besteht die Aufgabe darin, dieses Datum zu berechnen. Hierzu gibt es die Euler’sche Formel, deren Adaption in VBA Kern dieses Beitrages ist:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Public Function Ostersonntag(Jahr)
 
  Dim a, b, c, m, s, n, d, e
 
  If IsNull(Jahr) Then
    Ostersonntag = Null
  Else
    a = Jahr Mod 19
    b = Jahr Mod 4
    c = Jahr Mod 7
    m = ((8 * (Jahr / 100) + 13) / 25) - 2
    s = (Jahr / 100) - (Jahr / 400) - 2
    m = (15 + s - m) Mod 30
    n = (6 + s) Mod 7
    d = (m + 19 * a) Mod 30#
    If d = 29 Then
      d = 28
    Else
      If d = 28 And a >= 11 Then
        d = 27
      End If
    End If
    e = (2 * b + 4 * c + 6 * d + n) Mod 7
    Ostersonntag = VBA.DateAdd("d", d + e + 1, "21.03." & Jahr)
  End If
 
End Function

Zur Nutzung der Ostersonntagsberechnung gibt es dann noch die Funktion TagArt() dazu, die jedem der verschiedenen Tage einen numerischen Wert zuweist:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
Public Function TagArt(Datum)
 
  Dim TagMonat
  Dim O_Sonntag
 
  TagArt = 0
  If Not IsNull(Datum) Then
    TagMonat = Left(Datum, 6)
    Select Case TagMonat
      Case "01.01.": TagArt = 8 ' Neujahr
      Case "06.01.": TagArt = 9 ' Hl. Drei Könige
      Case "01.05.": TagArt = 14 ' Maifeiertag
      Case "15.08.": TagArt = 19 ' Mariä Himmelfahrt
      Case "03.10.": TagArt = 20 ' Tag der dt. Einheit
      Case "01.11.": TagArt = 21 ' Allerheiligen
      Case "24.12.": TagArt = 22 ' Heiligabend
      Case "25.12.": TagArt = 23 ' 1. Weihnachtstag
      Case "26.12.": TagArt = 24 ' 2. Weihnachtstag
      Case "31.12.": TagArt = 25 ' Silvester
      Case Else
        O_Sonntag = Ostersonntag(Year(Datum))
        If DateValue(Datum) = O_Sonntag Then
          TagArt = 12 ' Ostersonntag
        ElseIf VBA.DateAdd("d", -48, O_Sonntag) = DateValue(Datum) Then
          TagArt = 10 ' Rosenmontag
        ElseIf VBA.DateAdd("d", -2, O_Sonntag) = DateValue(Datum) Then
          TagArt = 11 ' Karfreitag
        ElseIf VBA.DateAdd("d", 1, O_Sonntag) = DateValue(Datum) Then
          TagArt = 13 ' Ostermontag
        ElseIf VBA.DateAdd("d", 39, O_Sonntag) = DateValue(Datum) Then
          TagArt = 15 ' Christi Himmelfahrt
        ElseIf VBA.DateAdd("d", 49, O_Sonntag) = DateValue(Datum) Then
          TagArt = 16 ' Pfingstsonntag
        ElseIf VBA.DateAdd("d", 50, O_Sonntag) = DateValue(Datum) Then
          TagArt = 17 ' Pfingstmontag
        ElseIf VBA.DateAdd("d", 60, O_Sonntag) = DateValue(Datum) Then
          TagArt = 18 ' Fronleichnam
        Else
          TagArt = WeekDay(DateValue(Datum), vbMonday)
        End If
    End Select
  End If
 
End Function

Dabei gelten die folgenden numerischen Werte für die verschiedenen Tagarten:

  • 01 = Montag
  • 02 = Dienstag
  • 03 = Mittwoch
  • 04 = Donnerstag
  • 05 = Freitag
  • 06 = Samstag
  • 07 = Sonntag
  • 08 = Neujahr
  • 09 = Hl. Drei Könige
  • 10 = Rosenmontag
  • 11 = Karfreitag
  • 12 = Ostersonntag
  • 13 = Ostermontag
  • 14 = Maifeiertag
  • 15 = Christi Himmelfahrt
  • 16 = Pfingstsonntag
  • 17 = Pfingstmontag
  • 18 = Fronleichnam
  • 19 = Mariä Himmelfahrt
  • 20 = Tag der dt. Einheit
  • 21 = Allerheiligen
  • 22 = Heiligabend
  • 23 = 1. Weihnachtstag
  • 24 = 2. Weihnachtstag
  • 25 = Silvester