Last active
December 24, 2024 12:42
-
-
Save maduck/e52bb3cdf0e176e3f5570eaafb456bac to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
# -*- coding: utf-8 -*- | |
""" Feiertage, die nicht auf ein Wochenende fallen → Bankfeiertage """ | |
import calendar | |
import datetime | |
import locale | |
locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8') | |
class Feiertage: | |
def __init__(self, jahr, sample_datum): | |
self.jahr = jahr | |
self.sample_datum = sample_datum | |
@staticmethod | |
def _oster_sonntag(jahr): | |
""" | |
Ostersonntag für den gregorianischen Kalender | |
""" | |
a = jahr % 19 # Mondparameter a | |
b, c = divmod(jahr, 100) # Säkularzahl c | |
d, e = divmod(b, 4) | |
f = (b + 8) / 25 # Säkulare Mondschaltung | |
g = (b - f + 1) / 3 | |
h = (19 * a + b - d - g + 15) % 30 | |
i, k = divmod(c, 4) | |
m = (32 + 2 * e + 2 * i - h - k) % 7 | |
n = (a + 11 * h + 22 * m) / 451 | |
monat, tag = divmod(int(h + m - 7 * n + 114), 31) | |
return datetime.date(jahr, monat, tag + 1) | |
def bewegliche_feiertage(self, jahr): | |
""" | |
Liste der Feiertage, die nicht auf ein Wochenende fallen müssen | |
""" | |
oster_sonntag = self._oster_sonntag(jahr) | |
return ( | |
(datetime.date(jahr, 1, 1), 'Neujahr'), | |
(oster_sonntag + datetime.timedelta(-2), 'Karfreitag'), | |
(oster_sonntag + datetime.timedelta(1), 'Ostermontag'), | |
(oster_sonntag + datetime.timedelta(39), 'Himmelfahrt'), | |
(oster_sonntag + datetime.timedelta(50), 'Pfingstmontag'), | |
(datetime.date(jahr, 5, 1), 'Tag der Arbeit'), | |
(datetime.date(jahr, 10, 3), 'Tag der dt. Einheit'), | |
(datetime.date(jahr, 11, 11), 'St. Martin'), | |
(datetime.date(jahr, 12, 6), 'Nikolaus'), | |
(datetime.date(jahr, 12, 24), 'Weihnachten'), | |
(datetime.date(jahr, 12, 25), 'erster Weihnachtsfeiertag'), | |
(datetime.date(jahr, 12, 26), 'zweiter Weihnachtsfeiertag'), | |
(datetime.date(jahr, 12, 31), 'Neujahr'), | |
) | |
@staticmethod | |
def _wochenende(datum: datetime.date) -> bool: | |
""" Prüft, ob ein Datum ein Wochenende ist. """ | |
return datum.weekday() in [5, 6] | |
def handelstag(self, datum): | |
""" Prüft, ob ein Datum ein Handelstag ist. """ | |
if datum in [i[0] for i in self.bewegliche_feiertage(datum.year)]: | |
return False | |
if self._wochenende(datum): | |
return False | |
return True | |
def feiertag(self, datum): | |
return not self.handelstag(datum) | |
@staticmethod | |
def sommerzeit(datum: datetime.date) -> bool: | |
""" returns True if date is between last sunday in march and last sunday in october """ | |
last_march = datetime.date(datum.year, 3, 31) | |
last_october = datetime.date(datum.year, 10, 31) | |
sunday = calendar.SUNDAY | |
delta_m = (last_march.weekday() - sunday) % 7 | |
delta_o = (last_october.weekday() - sunday) % 7 | |
sommerzeit_start = last_march - datetime.timedelta(days=delta_m) | |
sommerzeit_ende = last_october - datetime.timedelta(days=delta_o) | |
# print("[DEBUG] start: %s" % summertime_start.strftime('%d-%b-%Y')) | |
# print("[DEBUG] end: %s" % summertime_end.strftime('%d-%b-%Y')) | |
if (sommerzeit_start < datum) and (datum < sommerzeit_ende): | |
return True | |
return False | |
def pretty_output(self) -> str: | |
output = [f'Feiertage im Jahr {self.jahr}:'] | |
for feiertag in self.bewegliche_feiertage(self.jahr): | |
output.append('\t{0[0]:%A %d. %B %Y} \t\t {0[1]}'.format(feiertag)) | |
output.append( | |
f'{self.sample_datum:%A, der %d.%m.%Y}, ist {"" if self.handelstag(self.sample_datum) else "k"}ein Handelstag{" (Sommerzeit)" if self.sommerzeit(self.sample_datum) else ""}.') | |
return '\n'.join(output) | |
def __str__(self): | |
return self.pretty_output() | |
if __name__ == '__main__': | |
import argparse | |
parser = argparse.ArgumentParser() | |
parser.add_argument('-j', '--jahr', type=int, default=datetime.date.today().year) | |
parser.add_argument('-d', '--datum', type=datetime.date.fromisoformat, default=datetime.date.today()) | |
args = parser.parse_args() | |
meine_feiertage = Feiertage(args.jahr, args.datum) | |
print(meine_feiertage) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment