HowTo: Feiertage errechnen

Aloha,

da ich wohl bisher noch nicht der einzige war der Feiertage errechnen wollte dachte ich mir poste ich für die Nachwelt die Lösung.

Man kann sich alle beweglichen Feiertage errechnen wenn man von dem Ostersonntag ausgeht. Dementsprechend ist nur das die relevanz. Um den Ostersonntag zu errechnen nutzen wir die Gaußsche Formel.

Erst legen wir eine neue Funktion an:

GetHolidays(pYear as Integer = -1) as Dictionary

mit pYear = -1 können wir ein ein Jahr übergeben für welches wir die Feiertage haben wollen.

In der Funktion selbst legen wir erst die Parameter fest:

Dim dictHolidays dictHolidays = new Dictionary Dim da as new date Dim Jahr as Integer if pyear <> -1 then Jahr = pYear //given Year else Jahr = da.Year //current Year end if Dim a,b,c,d,e,f as Integer

Danach errechnen wir uns mit der gaußschen Formel den Ostersonntag:

[code] a = Jahr mod 19
b = Jahr / 100
c = (8 * b + 13) / 25 -2
d = b - (jahr / 400) - 2
e = (19 * (Jahr Mod 19) + ((15 -c +d) Mod 30)) Mod 30

if e = 28 then
if a > 10 then
e=27
end if
elseif e = 29 then
e = 28
end if
f = (d + 6 * e + 2 * (Jahr Mod 4) + 4 * (Jahr Mod 7) + 6) Mod 7[/code]

Nun haben wir alle Werte und schmeißen alles benötigte nun in ein DateObject. Im selben Zug fügen wir den Namen so wie Tag gleich in ein Dictionary ein.

Dim ostersonntag as new date ostersonntag.Year = Jahr ostersonntag.Month = 3 ostersonntag.Day = e+f+22+1 dictHolidays.Value(ostersonntag.SQLDate)="Ostersonntag"

Ab diesen Punkt können wir immer weiter referenzieren. Diverse Beispiele wären:

[code] Dim ostermontag as new date(ostersonntag)
ostermontag.Day = ostermontag.Day+1
dictHolidays.Value(ostermontag.SQLDate)=“Ostermontag”

Dim christihimmelfahrt as new date(ostersonntag)
christihimmelfahrt.Day = christihimmelfahrt.day + 39
dictHolidays.Value(christihimmelfahrt.SQLDate)=“Christi Himmelfahrt”

Dim pfingstsonntag as new date(ostersonntag)
pfingstsonntag.Day = pfingstsonntag.Day + 49
dictHolidays.Value(pfingstsonntag.SQLDate)=“Pfingstsonntag”[/code]

Das spiel kann man natürlich weiter treiben je nach dem was man benötigt.

Am ende geben wir noch das erstellte Dictionary zurück:

return dictHolidays

Und erfreuen uns :slight_smile:

lg
Christian

Danke fürs teilen, genau das was ich auch bald brauchen werde! :slight_smile:

Vielen Dank ebenfalls! Hab’s gerade getwittert und wusste nicht, ob du @ChristianBader bist oder ein anderer (oder gar nicht dort) – deshalb der Dank nur hier.

Aber sag mal, referenzierst du richtig? Müsste es nicht

Ostermontag.Day = Ostersonntag.day +1 usw. sein?

[quote=163150:@Ulrich Bogun]Vielen Dank ebenfalls! Hab’s gerade getwittert und wusste nicht, ob du @ChristianBader bist oder ein anderer (oder gar nicht dort) – deshalb der Dank nur hier.

Aber sag mal, referenzierst du richtig? Müsste es nicht

Ostermontag.Day = Ostersonntag.day +1 usw. sein?[/quote]
Nein. Er erzeugt Ostermontag mit dem Date von Ostersonntag, und addiert dann 1 dazu.

Ach, na klar! Hab den Constructor übersehen. Danke!

Gern geschehen - und nein idas bin ich nicht. wre /Cnypher aber ich bin auf Twitter eh nicht aktiv :slight_smile:

Hier noch kleines Sammelsorium der beweglichen Feiertage:
Verhltnis zum Ostersonntag
Karfreitag 2 Tage zuvor
Ostermontag 1 Tag danach
Christi Himmelfahrt 39 Tage danach
Pfingstsonntag 49 Tage danach
Pfingstmontag 50 Tage danach
Fronleichnam 60 Tage danach

Nach dem ersten Advent richten sich diese Feiertage:
Verhltnis zum 1. Advent (Der Sonntag vor Weihnachten - 21 Tage (Wenn gewnscht schreib ich dafr auch noch ne funktion, aber das ist ja nichts dramatisches)) :slight_smile:
Totensonntag 7 Tage davor
Bu und Bettag 11 Tage davor
Volkstrauertag 14 Tage davor

Und hier noch ein paar Statische Feiertage:
Neujahr 01.01.
Heilige 3 Knige 06.01.
Maifeiertag 01.05.
Friedensfest 08.08.
Mari Himmelfahrt 15.08.
Tag der Deutschen Einheit 03.10.
Reformationstag 31.10.
Allerheiligen 01.11.

  1. Weihnachten 25.12.
  2. Weihnachten 26.12.
    Silvester 31.12.

Thank you Christian, very generous of you sharing these information.

Buenas :wink:

Na dann fehlt ja vielleicht auch noch die richtige Berechnung der KALENDERWOCHE in Europa (da hat jede KW 7 Tage)
Beispiel: der 29.12.2014 lag in KW 1/2015 und dann nützt d.WeekofYear wenig …

Deshalb zwei extends für die date-class: KW liefert die KW nach DIN/ISO, KWJ das richtige Jahr dazu :wink:

Function KW(extends extDate as date) As integer
'* Ermittelt die KW des aktuellen Datums
Dim tmpD as new Date
Select Case extDate.DayOfWeek
case 1 '* SonntAG, also 3 Tage zurück
tmpD.TotalSeconds = extDate.TotalSeconds - 3 * 60 * 60 * 24
case 2 '* Montag bis Mittwoch, also vorwärts bis zum nächsten Donnerstag (4)
tmpD.TotalSeconds = extDate.TotalSeconds + 3 * 60 * 60 * 24
case 3 '* Dienstag, also vorwärts bis zum nächsten Donnerstag (4)
tmpD.TotalSeconds = extDate.TotalSeconds + 2 * 60 * 60 * 24
case 4 '* Mittwoch, also vorwärts bis zum nächsten Donnerstag (4)
tmpD.TotalSeconds = extDate.TotalSeconds + 1 * 60 * 60 * 24
case 6 '* Freitag , also zurück zum Donnerstag
tmpD.TotalSeconds = extDate.TotalSeconds - 1 * 60 * 60 * 24
case 7 '* Samstag, also zurück zum Donnerstag
tmpD.TotalSeconds = extDate.TotalSeconds - 2 * 60 * 60 * 24
case else '* --> 5
'–> bastscho !
tmpD.TotalSeconds = extDate.TotalSeconds
end select
return (tmpD.DayOfYear \ 7) + 1
End Function


Function KWJ(extends extDate as date) As Integer
'* Ermittelt das Jahr zur KW des aktuellen Datums
Dim tmpD as new Date
Select Case extDate.DayOfWeek
case 1 '* SonntAG, also 3 Tage zurück
tmpD.TotalSeconds = extDate.TotalSeconds - 3 * 60 * 60 * 24
case 2 '* Montag bis Mittwoch, also vorwärts bis zum nächsten Donnerstag (4)
tmpD.TotalSeconds = extDate.TotalSeconds + 3 * 60 * 60 * 24
case 3 '* Dienstag, also vorwärts bis zum nächsten Donnerstag (4)
tmpD.TotalSeconds = extDate.TotalSeconds + 2 * 60 * 60 * 24
case 4 '* Mittwoch, also vorwärts bis zum nächsten Donnerstag (4)
tmpD.TotalSeconds = extDate.TotalSeconds + 1 * 60 * 60 * 24
case 6 '* Freitag , also zurück zum Donnerstag
tmpD.TotalSeconds = extDate.TotalSeconds - 1 * 60 * 60 * 24
case 7 '* Samstag, also zurück zum Donnerstag
tmpD.TotalSeconds = extDate.TotalSeconds - 2 * 60 * 60 * 24
case else '* --> 5
'–> bastscho !
tmpD.TotalSeconds = extDate.TotalSeconds
end select
return tmpD.Year
End Function


Beispiel:

dim d as new Date(“2014-12-29”)
msgbox Str(d.KW) + “/” + str(d:KWJ) liefert 1/2015 :wink:

Vielleicht nützlich für Euch ?