Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- {
- "kirchliche_feiertage.pas" (Free Pascal/ GNU Pascal) computes the dates
- of church holidays, to compile run "fpc kirchliche_feiertage.pas" or
- "gpc -o kirchliche_feiertage kirchliche_feiertage.pas".
- Copyright (C) <December 3rd, 2015> Henning Polzer,
- send comments and error reports to: h underscore polzer at gmx dot de.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- }
- PROGRAM kirchliche_feiertage;
- CONST obergrenze = 5000; { Berechnungen nur bis zu diesem Jahr }
- TYPE Tdatum = RECORD
- t, m, j: integer { tag, monat, jahr }
- END;
- VAR fehlercode, { fuer Umwandlung der Kommandozeilenparameter }
- ks, ug, og: integer; { ks = kalenderstil }
- FUNCTION schaltjahr (stil, jahr: integer): integer;
- { Rueckgabewerte: 0 fuer Gemein-, 1 fuer Schaltjahr. }
- VAR ks, s: integer;
- BEGIN
- schaltjahr := 0;
- s := 0;
- ks := stil;
- IF ks = 1 THEN { jul. Kal. anwenden }
- IF jahr MOD 4 = 0 THEN s := 1;
- IF ks = 2 THEN { greg. Kal. anwenden }
- BEGIN
- IF jahr MOD 4 = 0 THEN s := 1;
- IF jahr MOD 100 = 0 THEN s := 0;
- IF jahr MOD 400 = 0 THEN s := 1
- END; { stil = 2 }
- schaltjahr := s
- END; { schaltjahr }
- FUNCTION datum_in_nummer (stil: integer; tagesdatum: Tdatum): integer;
- { verwandelt Tagesdatum in eine laufende Nummer }
- VAR dat: Tdatum;
- ks, schalttag, summe: integer;
- BEGIN
- datum_in_nummer := 0;
- dat := tagesdatum;
- summe := 0;
- ks := stil;
- { Ggf. Schalttag zur Addition bereithalten: }
- schalttag := schaltjahr (ks, dat.j);
- WITH dat DO
- CASE m OF
- 1: summe := t; { Schalttag fuer Januar ohne Bedeutung }
- 2: summe := 31 + t; { Schalttag beeinflusst Tagesnr. erst ab Maerz }
- 3: summe := 59 + t + schalttag;
- 4: summe := 90 + t + schalttag;
- 5: summe := 120 + t + schalttag;
- 6: summe := 151 + t + schalttag;
- 7: summe := 181 + t + schalttag;
- 8: summe := 212 + t + schalttag;
- 9: summe := 243 + t + schalttag;
- 10: summe := 273 + t + schalttag;
- 11: summe := 304 + t + schalttag;
- 12: summe := 334 + t + schalttag
- END; { case }
- datum_in_nummer := summe
- END; { datum_in_nummer }
- FUNCTION nummer_in_datum (stil, tagesnummer, jahreszahl: integer): Tdatum;
- { verwandelt laufende Nummer eines Tages in Datum }
- VAR ks, nr, tag, monat, jahr, schalttag: integer;
- tempdatum: Tdatum;
- BEGIN
- ks := stil;
- nr := tagesnummer;
- tag := 0;
- monat := 0;
- jahr := jahreszahl;
- tempdatum.j := jahreszahl; { Jahr bereits hier zuweisen }
- schalttag := schaltjahr (ks, jahr);
- IF schalttag = 0 THEN { Gemeinjahr }
- CASE nr OF
- 1.. 31: BEGIN tag := nr ; monat := 1 END;
- 32.. 59: BEGIN tag := nr - 31; monat := 2 END;
- 60.. 90: BEGIN tag := nr - 59; monat := 3 END;
- 91..120: BEGIN tag := nr - 90; monat := 4 END;
- 121..151: BEGIN tag := nr - 120; monat := 5 END;
- 152..181: BEGIN tag := nr - 151; monat := 6 END;
- 182..212: BEGIN tag := nr - 181; monat := 7 END;
- 213..243: BEGIN tag := nr - 212; monat := 8 END;
- 244..273: BEGIN tag := nr - 243; monat := 9 END;
- 274..304: BEGIN tag := nr - 273; monat := 10 END;
- 305..334: BEGIN tag := nr - 304; monat := 11 END;
- 335..365: BEGIN tag := nr - 334; monat := 12 END
- END { case } ELSE
- IF schalttag = 1 THEN { Schaltjahr }
- CASE nr OF
- 1.. 31: BEGIN tag := nr ; monat := 1 END;
- 32.. 60: BEGIN tag := nr - 31; monat := 2 END;
- 61.. 91: BEGIN tag := nr - 60; monat := 3 END;
- 92..121: BEGIN tag := nr - 91; monat := 4 END;
- 122..152: BEGIN tag := nr - 121; monat := 5 END;
- 153..182: BEGIN tag := nr - 152; monat := 6 END;
- 183..213: BEGIN tag := nr - 182; monat := 7 END;
- 214..244: BEGIN tag := nr - 213; monat := 8 END;
- 245..274: BEGIN tag := nr - 244; monat := 9 END;
- 275..305: BEGIN tag := nr - 274; monat := 10 END;
- 306..335: BEGIN tag := nr - 305; monat := 11 END;
- 336..366: BEGIN tag := nr - 335; monat := 12 END
- END; { case }
- tempdatum.t := tag;
- tempdatum.m := monat;
- nummer_in_datum := tempdatum
- END; { nummer_in_datum }
- FUNCTION konv_in_greg (julian_datum: Tdatum): Tdatum;
- { Verwandelt ein Datum im julian. Kalender in ein Datum im greg. Kalender.
- Nach: J. Bach, Die Zeit- und Festrechnung der Juden unter besonderer
- Beruecksichtigung der gaussschen Osterformel nebst einem immerwährenden
- Kalender, Freiburg i. B. 1908, 26.
- Vgl. auch Chr. Zeller, Kalender-Formeln, Acta Mathematica 9, 135.
- }
- VAR h, nr, neue_nr: integer;
- dat: Tdatum;
- BEGIN
- dat := julian_datum;
- h := trunc (dat.j / 100);
- { 1, weil Datum des jul. Kal. uebergeben, auch unten: }
- nr := datum_in_nummer (1, dat);
- neue_nr := nr + (h - trunc (h / 4) - 2);
- konv_in_greg := nummer_in_datum (1, neue_nr, dat.j)
- END; { konv_in_greg }
- FUNCTION wtnr (stil: integer; tagesdatum: Tdatum): integer;
- { Wochentag(snummer) bestimmen nach:
- Chr. Zeller, Kalender-Formeln, Acta Mathematica, Band 9 (1887), 131f.
- So. = 1, Mo. = 2, Di. = 3, Mi. = 4,
- Do. = 5, Fr. = 6, Sa. = 0
- }
- VAR h, j, k, ks, m, q: integer;
- dat: Tdatum;
- BEGIN
- dat := tagesdatum;
- ks := stil;
- q := dat.t;
- m := dat.m;
- j := trunc (dat.j / 100);
- k := dat.j - j * 100;
- IF m = 1 THEN { Januar als 13. Monat des VORjahres }
- BEGIN
- m := 13;
- k := k - 1
- END;
- IF m = 2 THEN { Februar als 14. Monat des VORjahres }
- BEGIN
- m := 14;
- k := k - 1
- END;
- IF ks = 1 THEN h := (q+trunc(26*(m+1)/10)+k+trunc(k/4)+5-j) ELSE
- IF ks = 2 THEN h := (q+trunc(26*(m+1)/10)+k+trunc(k/4)+trunc(j/4)-2*j);
- IF h < 0 THEN
- REPEAT
- h := h + 7
- UNTIL h >= 0;
- wtnr := h MOD 7
- END; { wtnr }
- PROCEDURE wochentag_ausgeben (nummer: integer);
- VAR n: integer;
- BEGIN
- n := nummer;
- CASE n OF
- 0: write ('Sa'); { Nummern wie bei Chr. Zeller, Kalender-Formeln, }
- 1: write ('So'); { Acta Mathematica, Band 9 (1887), 131f. gegeben }
- 2: write ('Mo');
- 3: write ('Di');
- 4: write ('Mi');
- 5: write ('Do');
- 6: write ('Fr')
- END;
- write ('.')
- END; { wochentag_ausgeben }
- PROCEDURE kirchliche_feiertage_ausgeben (untergr, obergr: integer);
- VAR jahr, u, o: integer;
- dat, neu: Tdatum;
- FUNCTION ostersonntag (stil: integer; jahr: integer): Tdatum;
- { Ostersonntag bestimmen nach:
- Chr. Zeller, Kalender-Formeln, Acta Mathematica, Band 9 (1887), 133 - 136.
- }
- VAR n, a, b, d, tag, monat, ks: integer;
- ostern: Tdatum;
- BEGIN
- ks := stil;
- n := jahr;
- monat := 4;
- IF ks = 1 THEN { julian. Kalender }
- BEGIN
- a := n MOD 19;
- b := (19*n-trunc (n/19)+15) MOD 30;
- d := (b+n+trunc (n/4)) MOD 7
- END;
- IF ks = 2 THEN
- BEGIN { gregian. Kalender }
- a := n MOD 19;
- b := (19*n-trunc(n/19)+15+(trunc(n/100)-trunc(n/300)-trunc(n/400))) MOD 30;
- d := (b + n + trunc (n/4) - (trunc (n/100) - trunc (n/400) - 2)) MOD 7
- END;
- IF (d = 0) AND (b = 29) THEN d := 7 ELSE
- IF (d = 0) AND (b = 28) AND (a > 10) THEN d := 7;
- tag := 21 + b + 7 - d;
- IF tag > 31 THEN tag := tag - 31 ELSE monat := 3;
- ostern.t := tag;
- ostern.m := monat;
- ostern.j := n;
- ostersonntag := ostern
- END; { ostersonntag }
- FUNCTION erster_advent (stil, jahr: integer): Tdatum;
- VAR basis, j, ks, tag: integer;
- dat: Tdatum;
- BEGIN
- j := jahr;
- ks := stil;
- { Advent 1582 schon nach der greg. Kalenderreform, deshalb: }
- IF j = 1582 THEN ks := 2;
- { 27.11. ist 331. Tag im Jahr + ggf. Schalttag: }
- basis := 331 + schaltjahr (ks, j);
- dat := nummer_in_datum (ks, basis, j);
- { Das folgende koennte in einer Formel zwar kuerzer
- ausgedrueckt werden, waere dann aber unuebersichtlicher: }
- CASE wtnr (ks, dat) OF
- 0: tag := basis + 1;
- 1: tag := basis; { Sonntag }
- 2: tag := basis + 6;
- 3: tag := basis + 5;
- 4: tag := basis + 4;
- 5: tag := basis + 3;
- 6: tag := basis + 2
- END; { case }
- erster_advent := nummer_in_datum (ks, tag, j)
- END; { erster_advent }
- FUNCTION konv_orth_weihnachten (julian_datum: Tdatum): Tdatum;
- { Datum des Weihnachtsfestes im julian. Kalender in entspr. Datum des
- greg. Kalender verwandeln, analog zu "konv_in_greg"; separate
- Funktion, weil Kalenderstil fuer Schaltjahresberechnung
- jahresunabhaengig julianisch sein muss.
- Wieder nach: Bach, Festrechnung, 26.
- }
- VAR h, nr, neue_nr: integer;
- dat: Tdatum;
- BEGIN
- dat := julian_datum;
- h := trunc (dat.j / 100);
- { 1, weil Datum des jul. Kal. uebergeben, auch unten: }
- nr := datum_in_nummer (1, dat);
- neue_nr := nr + (h - trunc (h / 4) - 2);
- IF neue_nr > 365 + schaltjahr (1, dat.j) THEN { immer jul. Kalender }
- BEGIN
- neue_nr := neue_nr - (365 + schaltjahr (1, dat.j));
- dat.j := dat.j + 1 { Jahresgrenze ueberschritten }
- END; { if }
- konv_orth_weihnachten := nummer_in_datum (1, neue_nr, dat.j)
- END; { konv_orth_weihnachten }
- BEGIN { kirchliche_feiertage_ausgeben }
- u := untergr;
- o := obergr;
- IF o > obergrenze THEN o := obergrenze;
- FOR jahr := u TO o DO
- BEGIN
- IF jahr < 1583 THEN ks := 1 { 1 fuer julianischen Stil }
- ELSE ks := 2; { 2 fuer gregorianischen Stil }
- dat := ostersonntag (ks, jahr); { Westkirche }
- neu := nummer_in_datum (ks, datum_in_nummer (ks, dat) - 46, jahr);
- write ('Aschermittw.: ', neu.t:2, '.', neu.m:2, '.', neu.j, '; ');
- neu := nummer_in_datum (ks, datum_in_nummer (ks, dat) - 2, jahr);
- write ('Karfreitag : ', neu.t:2, '.', neu.m:2, '.', neu.j, '; ');
- write ('Ostern: ', dat.t:2, '.', dat.m:2, '.', dat.j, '; ');
- neu := nummer_in_datum (ks, datum_in_nummer (ks, dat) + 39, jahr);
- write ('Chr. Himmelfahrt: ', neu.t:2, '.', neu.m:2, '.', neu.j, '; ');
- neu := nummer_in_datum (ks, datum_in_nummer (ks, dat) + 49, jahr);
- writeln ('Pfingsten: ', neu.t:2, '.', neu.m:2, '.', neu.j, '; ');
- neu := nummer_in_datum (ks, datum_in_nummer (ks, dat) + 60, jahr);
- write ('Fronleichnam: ', neu.t:2, '.', neu.m:2, '.', neu.j, '; ');
- neu := nummer_in_datum (ks, datum_in_nummer (ks, dat) + 68, jahr);
- write ('Herz-Jesu-Fr.: ', neu.t:2, '.', neu.m:2, '.', neu.j, '; ');
- write ('Mariae Himmelfahrt: '); { Wochentag ausgeben }
- WITH neu DO
- BEGIN
- t := 15;
- m := 8;
- j := jahr
- END; { with }
- wochentag_ausgeben (wtnr (ks, neu));
- dat := erster_advent (ks, jahr);
- { Buss-/Bettag: }
- neu := nummer_in_datum (ks, datum_in_nummer (ks, dat) - 11, jahr);
- write ('; Buss/Bettag: ', neu.t:2, '.', neu.m:2, '.', neu.j, '; ');
- { 1. Advent: }
- write ('1. Advent: ', dat.t:2, '.', dat.m:2, '.', dat.j, '; ');
- writeln;
- IF jahr >= 1582 THEN { Orthodoxie behaelt jul. Kalender bei }
- BEGIN
- IF jahr > 1582 THEN { Ostern noch vor greg. Reform }
- BEGIN
- write ('Orthodoxes Osterfest : ');
- dat := ostersonntag (1, jahr); { 1 fuer Formel des jul. Kalenders }
- write (dat.t:2, '.', dat.m:2, '.', dat.j, ' [julian.], ');
- neu := konv_in_greg (dat);
- write ('entspr. ', neu.t:2, '.', neu.m:2, '.', neu.j, ' im ');
- writeln ('greg. Kalender. ')
- END; { if }
- { Weihnachten 1582 nach Kalenderreform: }
- write ('Orthodoxes Weihnachten: 25.12.', jahr, ' [julian.], ');
- WITH dat DO
- BEGIN
- t := 25;
- m := 12;
- j := jahr
- END;
- neu := konv_orth_weihnachten (dat);
- write ('entspr. ', neu.t:2, '.', neu.m:2, '.', neu.j, ' im ');
- writeln ('greg. Kalender. ')
- END; { if [orth. Ostern] }
- writeln
- END { for }
- END; { kirchliche_feiertage_ausgeben }
- BEGIN { Hauptprogramm }
- val (paramstr (1), ug, fehlercode); { Ggf. Fehlerbehandlung einfuegen }
- val (paramstr (2), og, fehlercode);
- {
- Sample output:
- ./kirchliche_feiertage 2015 2016
- Aschermittw.: 18. 2.2015; Karfreitag : 3. 4.2015; Ostern: 5. 4.2015; Chr. Himmelfahrt: 14. 5.2015; Pfingsten: 24. 5.2015;
- Fronleichnam: 4. 6.2015; Herz-Jesu-Fr.: 12. 6.2015; Mariae Himmelfahrt: Sa.; Buss/Bettag: 18.11.2015; 1. Advent: 29.11.2015;
- Orthodoxes Osterfest : 30. 3.2015 [julian.], entspr. 12. 4.2015 im greg. Kalender.
- Orthodoxes Weihnachten: 25.12.2015 [julian.], entspr. 7. 1.2016 im greg. Kalender.
- Aschermittw.: 10. 2.2016; Karfreitag : 25. 3.2016; Ostern: 27. 3.2016; Chr. Himmelfahrt: 5. 5.2016; Pfingsten: 15. 5.2016;
- Fronleichnam: 26. 5.2016; Herz-Jesu-Fr.: 3. 6.2016; Mariae Himmelfahrt: Mo.; Buss/Bettag: 16.11.2016; 1. Advent: 27.11.2016;
- Orthodoxes Osterfest : 18. 4.2016 [julian.], entspr. 1. 5.2016 im greg. Kalender.
- Orthodoxes Weihnachten: 25.12.2016 [julian.], entspr. 7. 1.2017 im greg. Kalender.
- }
- kirchliche_feiertage_ausgeben (ug, og)
- END.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement