PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Feiertagsberechnung


pate33
27.05.2002, 15:15
Hi,

kennt jemand nen algorithmus zur berechnung aller feiertage im jahr?

am liebsten als oracle stored procedure. :D

thanks


Bolle
27.05.2002, 16:04
hmm ich glaub das ist nich möglich, denn ich hab da noch kein system bei endeckt.
die sind doch wohl eher ziemlich willkürlich gesetzt worden, so is ein algorithmus meiner meinung nach eher nich möglich.

pate33
27.05.2002, 16:09
hm, doch. fuer ostern gibt es ja definitiv was... soll angeblich extrem lang sein... :D

ich denk schon, dass man da nen algorithmus aufstellen kann... :rolleyes:

Bolle
27.05.2002, 16:12
hmm stimmt ostern kann sein. aber was willst du da berechnen hast kein kalender? ;) hmm ne im ernst. die meisten daten sind doch fest, da brauch man imho nichts berechnen,

pate33
27.05.2002, 16:22
ja, aber ich brauch das fuer oracle... momentan haben wir ne tabelle, wo wir die feiertage eintragen... und das ist bloed, denn wenn es einer vergisst, stimmen die statistiken nimmer... :(

Bolle
27.05.2002, 21:16
hmm ok, dann trag doch einmal alle feiertage in eine tabelle ein und füll das dann in die neue tabelle ein. is zwar nicht grad elegant aber was solls nur das mit den beweglichen feiertagen wie ostern und so, dass wäre mal ne interresante sache sich dazu was zu überlegen.

Diogenes
28.05.2002, 12:03
Es gibt in der Römisch-Katholischen Kirche 2 Typen von Feiertagen:

Feste Feste : Die finden immer an einem bestimmten Termin statt, wie zum Beispiel der Christtag, der immer am 25. Dezember gefeiert wird. Das sollte einfach sein.

Weniger einfach sind zugegebenermaßen die beweglichen Feste. Die sind alle relativ zum Ostersonntag gesetzt, wobei jeder Feiertag seinen eigenen Abstand zum Ostersonntag hat. Der wiederum ist der erste Sonntag, der auf den ersten Vollmond im Frühling folgt. Das ist die Definition. Jetzt kann man einen Algorithmus daraus basteln, wenn man die länge des tropischen Jahres (Zeit, die die Sonne braucht, um den Frühlingspunkt 2 mal zu erreichen) und des synodischen Monats (Zeit von Neumond zu Neumond) kennt. Und einen exakten Termin (Tag, Stunde, Minut, Sekunde) für 1 Vollmond braucht man auch. Noch eine Anmerkung: Das Gregorianische Kalenderjahr ist um etwa 0.0003 Tage länger als das astronomische, tropische Jahr. Macht die Sache ein wenig komplizierter.

Little
04.06.2002, 13:06
und vergiss die regionalen Feiertage nicht, die sind noch verrückter einzubringen

nj0y
14.06.2002, 11:18
Ich hab vor längerer Zeit mal einen Kalender geschrieben. Hier den wichtigen Ausschnitt aus der relevanten Routine zur Feiertagsberechnung (incl. der regionalen Feiertage):

void __fastcall CalcFeiertage(int jahr)
{
int t, ostern, o_tag, o_monat, a, b, c, d, e;

o_tag = o_monat = 0;
a = jahr % 19; b = jahr % 4; c = jahr % 7;
d = (19 * a + 24) % 30; e = (2 * b + 4 * c + 6 * d + 5) % 7;
if(d == 29 && e == 6)
{
o_tag = 29; o_monat = 4;
}
else if(d == 28 && e == 6)
{
o_tag = 18; o_monat = 4;
}
else
{
if(d + e < 10)
{
o_tag = 22 + d + e;
o_monat = 3;
}
else
{
o_tag = d + e - 9;
o_monat = 4;
}
}
ostern = DayOfYear(o_tag, o_monat, jahr);

AddFT(1, 1, "Neujahr", ALL);
AddFT(6, 1, "Hl. Drei Könige", BW | BAY | SAA);
AddFT(14, 2, "Valentin", 0);
AddFT(ostern - 48, 0, "Rosenmontag", 0);
AddFT(ostern - 47, 0, "Fastnacht", 0);
AddFT(ostern - 46, 0, "Aschermittwoch", 0);
// 20.03. Frühlingsanfang
if(jahr == 1980) AddFT(6, 4, "Beginn Sommerzeit", 0);
else if(jahr > 1980) AddFT(DayOfYear(31, 3, jahr) - WotaSo(31, 3, jahr), 0, "Beginn Sommerzeit", 0);
AddFT(ostern - 7, 0, "Palmsonntag", 0);
AddFT(ostern - 3, 0, "Gründonnerstag", 0);
AddFT(ostern - 2, 0, "Karfreitag", ALL);
AddFT(ostern, 0, "Ostern", ALL);
AddFT(ostern + 1, 0, "Ostern", ALL);
AddFT(ostern + 7, 0, "Weißer Sonntag", 0);
AddFT(1, 5, "Maifeiertag", ALL);
t = DayOfYear(30, 4, jahr) - WotaSo(30, 4, jahr) + 14;
if(t == ostern + 49) t -= 7;
AddFT(t, 0, "Muttertag", ALL);
AddFT(ostern + 39, 0, "Christi Himmelfahrt", ALL);
AddFT(ostern + 49, 0, "Pfingsten", ALL);
AddFT(ostern + 50, 0, "Pfingsten", ALL);
// 21.06. Sommeranfang
AddFT(ostern + 60, 0, "Fronleichnam", BW | BAY | HES | NRW | RPL | SAR);
AddFT(27, 6, "Siebenschläfer", 0);
AddFT(15, 8, "Mariä Himmelfahrt", SAR | BAY);
// 22.09. Herbstanfang
AddFT(29, 9, "Michaelis", 0);
AddFT(DayOfYear(29, 9, jahr) + 7 - WotaSo(29, 9, jahr), 0, "Erntedank", 0);
AddFT(3, 10, "Deutsche Einheit", ALL);
if(jahr == 1980) AddFT(28, 9, "Ende Sommerzeit", 0);
else if(jahr > 1980 && jahr <= 1995) AddFT(DayOfYear(30, 9, jahr) - WotaSo(30, 9, jahr), 0, "Ende Sommerzeit", 0);
else if(jahr >= 1996) AddFT(DayOfYear(31, 10, jahr) - WotaSo(31, 10, jahr), 0, "Ende Sommerzeit", 0);
AddFT(31, 10, "Reformationstag", BRB | MVP | SAX | SAA | THR);
AddFT(1, 11, "Allerheiligen", BW | BAY | NRW | RPL | SAR);
AddFT(11, 11, "Martin", 0);
AddFT(DayOfYear(24, 12, jahr) - WotaSo(24, 12, jahr) - 5 * 7, 0, "Volkstrauertag", 0);
AddFT(DayOfYear(24, 12, jahr) - WotaSo(24, 12, jahr) - 4 * 7 - 4, 0, "Buß- und Bettag", SAX);
AddFT(DayOfYear(24, 12, jahr) - WotaSo(24, 12, jahr) - 4 * 7, 0, "Totensonntag", 0);
t = DayOfYear(24, 12, jahr) - WotaSo(24, 12, jahr);
AddFT(t, 0, "4. Advent", 0);
AddFT(t - 7, 0, "3. Advent", 0);
AddFT(t - 14, 0, "2. Advent", 0);
AddFT(t - 21, 0, "1. Advent", 0);
AddFT(6, 12, "Nikolaus", 0);
// 21.12. Winteranfang
AddFT(24, 12, "Heiligabend", 0);
AddFT(25, 12, "Weihnachten", ALL);
AddFT(26, 12, "Weihnachten", ALL);
AddFT(31, 12, "Silvester", 0);
}

int __fastcall DayOfYear(int t, int m, int j)
{
TDateTime present, StartOfYear;
unsigned short day, month, year;

present = TDateTime(j, m, t);
present.DecodeDate(&year, &month, &day);
StartOfYear = EncodeDate(year, 1, 1);
return (int) present - (int) StartOfYear + 1;
}

int __fastcall WotaSo(int t, int m, int j)
{
TDateTime dt;

dt = EncodeDate(j, m, t);
return dt.DayOfWeek() - 1;
}

Die letzten beiden Routinen sind C++Builder-spezifisch, können aber natürlich in andere Programmsprachen sinngemäß übersetzt werden.

AddFT kriegt übrigens vier Parameter: Tag, Monat, Bezeichnung, Bundesländer. Bundesländer ist ein Bitfeld. Wenn Monat = 0, gibt Tag den Tag im ganzen Jahr an.