(* Berechnung der variablen Feiertag
   Quelltext für Turbo Pascal 7.0
   (c) Ulrich Eberhardt 1997
   Quelle: www.eberardt-koenig.de               *)

(* Der Aufruf des Programms kann mit Übergabeparameter erfolgen.
   Der Parameter muá eine vierstellige Jahreszahl sein, ansonsten wird
   das aktuelle Jahr genommen                   *)


(* Hinweis:
   der DOS-Zeichensatz, den TP verwendet ist der ASCII-Zeichensatz.
   Nur für die Kommentare wurde ANSI verwendet. *)




Program Feiertage;
uses    dos, crt;
var     Tag   : Integer;
        Monat : Integer;
        Jahr  : Integer;
        JulTag: LongInt;
        I     : Integer;

Function JulianischerTag (tag,monat,jahr:integer):longint;
(* Berechnet aus dem Gregorianischen Datum die sog. Julianischen Tage.
   Aus den Julianischen Tagen läßt sich sehr leicht der Wochentag eines
   Datums ermitteln. Auch die Anzahl der Tage, die zwischen 2 Terminen
   liegt, läßt sich aus der Differenz der Julianischen Tage errechnen.  *)

Var c,ja:LongInt;
begin
  if monat >2 then dec(monat,3) else begin
    inc(monat,9);dec(jahr);
  end;
  c:= jahr div 100;
  ja:=jahr mod 100;
  JulianischerTag:=146097*c div 4 + 1461*ja div 4 + (153*Monat+2) div 5 + Tag + 1721119;
end; {of JulianischerTag}

Procedure GregorDatum (var Tag,Monat,Jahr:integer;JulTag:longint);
(* Berechnet aus den Julianischen Tagen unser Gregorianisches Datum. *)

Var y,d:longint;

begin
  dec(JulTag,1721119);
  y:=(4*JulTag - 1 ) div 146097;
  JulTag:=4*JulTag - 1 - 146097*y;
  d:=JulTag  div 4;
  JulTag:=(4*d + 3) div 1461;
  d:=(4*d + 7 - 1461*JulTag) div 4;
  Monat:=(5*d - 3) div 153; d:=5*d - 3 - 153*Monat;
  Tag:=(d+5) div 5;
  Jahr:=100*y + JulTag;
  if Monat<10 then inc(Monat,3) else
  begin
    dec(Monat,9);inc(Jahr);
  end;
end; {of GregorDatum}

Function WochenTag(Tag,Monat,Jahr:integer):integer;
(* ermittelt die Nummer des Wochentags zu einem Datum. Mo=0 bis So=6 *)

begin
  WochenTag:=JulianischerTag(Tag,Monat,Jahr) mod 7;
end; {of WochenTag}


Function Ostersonntag(Jahr :integer):longint;
(* Errechnet den Julianischen Tag von Ostern zu einem gegebenen Jahr.
   Alle anderen beweglichen Feiertage liegen in konstanten Abständen zu
   Ostern. Der Algorithmus stammt von Gauss. *)

var a,b,c,d:integer;

begin
  a:=jahr div 100 - jahr div 400 +4;
  b:=a - jahr div 300 + 11;
  c:=((( jahr mod 19)*19)+b) mod 30;
  d:=(((jahr mod 4)*2 + 4*jahr + 6*c + a) mod 7) + c -9;
  if d<1 then
   begin
    Ostersonntag:=JulianischerTag(31+d,3,Jahr);
   end
  else
   begin
    if (d=26)or((c=28) and (d=25) and ((11*(b+1) mod 30)< 19)) then dec(d,7);
    Ostersonntag:=JulianischerTag(d,4,Jahr);
   end;
end; {of Ostersonntag}

Function BussUndBettag(Jahr:integer):integer;
(* Der Buß- und Bettag ist der Mittwoch vor dem letzten Sonntag des
   Kirchenjahres. Er liegt immer zwischen dem 16. und 22. November
   und 1,5 Wochen vor dem Ersten Advent *)

var i:integer;
begin
 i:=Wochentag(1,11,Jahr);
 if i<2 then BussUndBettag:=17-i else BussUndBettag:=24-i;
end; {of BussUndBettag}


Function ErsterAdvent(Jahr:integer):LongInt;
(* Der 1. Advent ist der Beginn des Kirchenjahres.
   Er ist der vierte Sonntag vor Heilig Abend, wenn
   dieser kein Sonntag ist (sonst nur der 3. Sonntag) *)

var y:longint;
begin;
 y := JulianischerTag(24,12,jahr);
 if (y mod 7)<6 then y:=y-(y mod 7)-1;
 ErsterAdvent := y-21;
end; {of ErsterAdvent}

function Rosenmontag(jahr:integer):longint;
var y:longint;
begin;
 y := Ostersonntag(jahr);
 Rosenmontag := y-48;
end; {of Rosenmontag}


function Karfreitag(jahr:integer):longint;
var y:longint;
begin;
 y := Ostersonntag(jahr);
 Karfreitag := y-2;
end; {of Karfreitag}

function Ostermontag(jahr:integer):longint;
var y:longint;
begin;
 y := Ostersonntag(jahr);
 Ostermontag := y+1;
end; {of Ostermontag}

function WeisserSonntag(jahr:integer):longint;
var y:longint;
begin;
 y := Ostersonntag(jahr);
 Weissersonntag := y+7;
end; {of WeisserSonntag}

function Palmsonntag(jahr:integer):longint;
var y:longint;
begin;
 y := Ostersonntag(jahr);
 Palmsonntag := y-7;
end; {of Palmsonntag}

function Ch_Himmelfahrt(jahr:integer):longint;
var y:longint;
begin;
 y := Ostersonntag(jahr);
 Ch_Himmelfahrt := y+39;
end; {of Christi Himmelfahrt}

function Pfingstsonntag(jahr:integer):longint;
var y:longint;
begin;
 y := Ostersonntag(jahr);
 Pfingstsonntag := y+49;
end; {of Pfingstsonntag}


function Pfingstmontag(jahr:integer):longint;
var y:longint;
begin;
 y := Ostersonntag(jahr);
 Pfingstmontag := y+50;
end; {of Pfingstmontag}

function Fronleichnam(jahr:integer):longint;
var y:longint;
begin;
 y := Ostersonntag(jahr);
 Fronleichnam := y+60;
end; {of Fronleichnam}


Procedure ParameterAuswertung;
(* Sie dient zur Auswertung der šbergabeparameter beim Aufruf des Programms.
   Der Parameter muß eine vierstellige Jahreszahl sein, ansonsten wird das
   aktuelle Jahr genommen *)
var   j, m, d   :Word;
      Wochentag :Word;

BEGIN;
 val(ParamStr(1),Jahr,I);
 If (ParamStr(1)='') or (Jahr<1901) Then
 begin
   GetDate(j,m,d,Wochentag);
   Jahr:=j;
 end;
END; {of ParameterAuswertung}


Procedure Datum(JulTag:LongInt);
(* Sie rechnet das Datum im Format des Julianischen Kalender wieder
   in das Gregorianische Datum mit Tag, Monat, Jahr und Wochentag um. *)
const     WochenTag  : array [0..6] of String[10] =
                       ('Montag','Dienstag','Mittwoch',
                       'Donnerstag','Freitag','Samstag','Sonntag');
          Monatsname : Array [1..12] of String[9] =
                       ('Januar   ','Februar  ','M„rz     ','April    ',
                        'Mai      ','Juni     ','Juli     ','August   ',
                        'September','Oktober  ','November ','Dezember ');

begin;
 GregorDatum(Tag,Monat,Jahr,JulTag);
{ Write(Tag:2,'.',Monat:2,'.',Jahr);          Ausgabe in der Form TT.MM.JJJJ}
 Write(Tag:2,'. ',Monatsname[Monat],Jahr);   {Ausgabe in der Form TT. Monat Jahr}
 Write(' (',WochenTag[JulTag mod 7],')');
end; {of Datum}


Begin {of Hauptprogramm}
 ClrScr;
 ParameterAuswertung;

 Write('Hl. drei K”nige  :  '); Datum(JulianischerTag(06,01,Jahr)); WriteLN;
 Write('Rosenmontag      :  '); Datum(Rosenmontag(Jahr)); WriteLN;
 WriteLN;
 Write('Palmsonntag      :  '); Datum(Palmsonntag(Jahr)); WriteLN;
 Write('Karfreitag       :  '); Datum(Karfreitag(Jahr));  WriteLN;
 Write('Ostersonntag     :  '); Datum(Ostersonntag(Jahr)); WriteLN;
 Write('Weiáer Sonntag   :  '); Datum(Weissersonntag(Jahr)); WriteLN;
 Write('Chr. Himmelfahrt :  '); Datum(Ch_Himmelfahrt(Jahr)); WriteLN;
 WriteLN;
 Write('Tag der Arbeit   :  '); Datum(JulianischerTag(01,05,Jahr)); WriteLN;
 WriteLN;
 Write('Pfingstsonntag   :  '); Datum(Pfingstsonntag(Jahr)); WriteLN;
 Write('Fronleichnam     :  '); Datum(Fronleichnam(Jahr)); WriteLN;
 Write('Maria Himmelfahrt:  '); Datum(JulianischerTag(15,08,Jahr)); WriteLN;
 WriteLN;
 Write('Tag der Einheit  :  '); Datum(JulianischerTag(03,10,Jahr)); WriteLN;
 WriteLN;
 Write('Allerheiligen    :  '); Datum(JulianischerTag(01,11,Jahr)); WriteLN;
 Write('Buá- und Bettag  :  '); Write(BussUndBettag(Jahr),'. November ',Jahr,' (Mittwoch)'); WriteLN;
 WriteLN;
 Write('Erster Advent    :  '); Datum(ErsterAdvent(Jahr)); WriteLN;
{ Write('Antje Bchner   :  '); Datum(JulianischerTag(17,12,Jahr)); WriteLN;}
 Write('Heilig Abend     :  '); Datum(JulianischerTag(24,12,Jahr)); WriteLN;
 Write('Silvester        :  '); Datum(JulianischerTag(31,12,Jahr));
end. {of  Hauptprogramm}
