Zurück zum Inhaltsverzeichnis - Lösungen und Tipps
- [ F.Seck | F.Seck ]
Das herunterladbare Skript/Makro erstellt einen Kalender zu einem beliebigen Jahr n. Chr. Das Ergebnis wird mit #*satz aufbereitet und ausgegeben.
kalendermak.tf [24 KB]
N.B.: Vor dem Starten muss die Makrodatei 'kalendermak.tf' als Makrodatei definiert werden:
Gib Kommando >#DE,kalendermak.tf
Aufruf mit Spezifikationen:
Gib Kommando >$kalender,jahr,stil
Beispiele:
Gib Kommando >$kalender,jahr Ausgabe eines Kalenders zum Jahr jahr, wobei bis 1581 der julianische, ab 1582 der gregorianische Kalender zugrunde gelegt wird Gib Kommando >$kalender,jahr,alt dto., auch für die Jahre nach 1581 wird der julianische Kalender ("alter Stil") zugrunde gelegt Zu stil ist nur die Angabe "alt" sinnvoll.
Zur Erstellung eines immerwährenden Kalenders mit #KOPIERE
(allerdings ohne Angabe der Sonntagsnamen) siehe hier.
- [ F.Seck | F.Seck ]
Mit dem folgenden Makro/Skript können alle Jahre zwischen 326 und 2100 aufgelistet werden, in denen der Ostersonntag auf ein bestimmtes Datum fiel/fällt. Angegeben werden kann dabei, ob der julianische („alter Stil“) oder der gregorianische Kalender („neuer Stil“, ab 1582 je nach Land) zugrunde gelegt werden soll (Voreinstellung: neuer Stil). Außerdem kann der Zeitraum eingeschränkt werden.
Vorbemerkung: Auf dem Konzil von Nicäa (Mai bis Juli 325) wurde das Datum des Osterfestes auf den ersten Sonntag nach dem ersten Frühlingsvollmond festgelegt. Vereinbartes Datum für den dem Frühlingsvollmond vorangehenden Frühlingsanfang ist der 21. März, sodass der früheste Ostersonntag auf den 22. März, der späteste auf den 25. April fällt.
Ablauf und Aufruf:
$$- Das Makro hat folgende Spezifikationen (* = Voreinstellung) $$- $$- TAG = zahl Tagesdatum des Ostertermins (1 bis 31) $$- MONAT = zahl Monatsnummer des Ostertermins $$- STIL = NEU * Osterdatum nach neuem Stil berechnen $$- = ALT Osterdatum nach altem Stil berechnen $$- ERSTJAHR = 326 * Jahre ab 326 berechnen $$- = zahl Jahre ab dem angegebenen Jahr berechnen $$- LETZTJAHR = 2100 * Jahre bis 2100 berechnen $$- = zahl Jahre bis zum angegebenen Jahr berechnen $$- $$! tag, monat, stil=neu, erstjahr=326, letztjahr=2100 $$ MODE TUSCRIPT, {} - ist zu Tag und Monat überhaupt etwas angegeben? IF (tag.EQ.'LEER') ERROR/STOP "Angabe zu TAG fehlt!" IF (monat.EQ.'LEER') ERROR/STOP "Angabe zu MONAT fehlt!" - sind die Angaben zu Tag, Monat, Erstjahr, Letztjahr numerisch? - ("teilw" enthält den Namen der Variablen, z.B. "Monat", "@teilw" - ihren Inhalt, z.B. "4".) SET var = "TAG'MONAT'ERSTJAHR'LETZTJAHR" LOOP teilw = var IF (@teilw.NE.'ZIFFERN') THEN ERROR/STOP "Angabe ",@teilw," zu ",teilw," ist nicht numerisch" ENDIF ENDLOOP - ist die Angabe zu Erstjahr sinnvoll? IF (erstjahr.LT.326) THEN PRINT/ERROR "Erstjahr vor 326 nicht sinnvoll, weil der geltende Oster-" PRINT/ERROR "termin (Sonntag nach dem ersten Frühlingsvollmond) erst" ERROR/STOP "beim Konzil von Nikaia (Mai bis Juli 325) bestimmt wurde." ENDIF - ergeben tag und monat ein mögliches Tagesdatum? SET wtg = DATE (NUMBER,tag,monat,2004,egal) IF (wtg.EQ.0) ERROR/STOP tag,".",monat,". ist kein mögliches Tagesdatum!" - ergeben tag und monat ein mögliches Osterdatum? - frühestes Osterdatum: 22. März, spätestes: 25. April IF (monat.LT.3.OR.monat.GT.4.OR. monat.EQ.3.AND.tag.LT.22.OR. monat.EQ.4.AND.tag.GT.25) THEN PRINT/ERROR "Der ",tag,".",monat,". ist kein mögliches Osterdatum." ERROR/STOP "Frühester Ostertermin: 22. März, spätester: 25. April." ENDIF - Schleife über alle Jahre des Zeitraums erstjahr bis letztjahr: SET treffer = 0, zeile = " ", i = 0 LOOP jahr = erstjahr, letztjahr IF (stil.AB."neu") THEN SET egal = DATE (EASTER,ostag,osmonat,jahr,auchegal) ELSEIF (stil.AB."alt","julianisch") THEN SET egal = DATE (EASTER/JULIAN,ostag,osmonat,jahr,auchegal) ELSE PRINT/ERROR "Falsche Angabe ",stil," zur Spezifikation STIL." PRINT/ERROR "Zulässig sind (auch abgekürzt) ALT (gleichwertig" ERROR/STOP "JULIANISCH) und NEU (Voreinstellung)." ENDIF - Jahre mit dem gesuchten Ostertermin (Treffer) ermitteln, unten mit - CONCAT die Ausgabe in Zeilen zu 10 Jahren abteilen: IF (ostag.EQ.tag.AND.osmonat.EQ.monat) THEN - ausgeben, wenn die Zeile 10 Jahre enthält (PRINT): IF (i.EQ.10) THEN - Jahre unter 1000 durch vorangestelltes Blank vierstellig machen: SET zeile = EXCHANGE (zeile, "| {3}{\0}{]}{0} | {+2=}|") - kleiner Abstand nach 5 Jahren: SET zeile = EXCHANGE (zeile, "| | |", 30, 31) PRINT zeile - nach PRINT Variablen für Ausgabe zurücksetzen: SET i = 0, Zeile = " " ENDIF SET treffer = treffer + 1 SET i = i+1, zeile = CONCAT (zeile," ",jahr) ENDIF ENDLOOP - Meldung, wenn kein Treffer: IF (treffer.EQ.0) THEN PRINT/ERROR "Zwischen ",erstjahr," und ",letztjahr," kein Jahr mit Osterdatum ",tag,".",monat,"." ELSEIF (i.NE.0) THEN SET e = "e" IF (treffer.EQ.1) SET e = "" SET zeile = EXCHANGE (zeile, "| {3}{\0}{]}{0} | {+2=}|") SET zeile = EXCHANGE (zeile, "| | |", 30, 31) - letzte Zeile ausgeben, falls kürzer als 10 Jahre; Endmeldung PRINT zeile SET meldung = " Von {erstjahr} bis {letztjahr} {treffer} Jahr{e} mit Ostertermin {tag}.{monat}." SET meldung = EXCHANGE (meldung,"|.3.|. März.|.4.|. April.|") PRINT "" PRINT meldung ENDIF
Das Skript befindet sich auch in folgender Makrodatei:
kalendermak.tf [24 KB]
N.B.: Vor dem Starten muss diese Datei als Makrodatei definiert werden:
Gib Kommando >#DE,kalendermak.tf
Aufruf mit Spezifikationen wie oben:
Gib Kommando >$ostern,........
Aufgabe und Herleitung
Anwendungsbeispiel: Ein altes Dokument, z.B. ein Brief, trägt die für den damaligen Adressaten eindeutige,
für den heutigen Leser aber unzureichende Datierung „am 5. Aprilis, Charfreitag“.
Aufgrund des Schriftduktus und anderer Indizien ist das Dokument dem letzten Drittel des 17. Jahrhunderts zuzuordnen. Was tun?
Für diese Fälle hat TUSTEP eine für alle Jahre n. Chr. definierte Datumsfunktion, die im Programm KOPIERE und unter der Scriptsprache TUSCRIPT zur Verfügung steht.
Wir probieren es mit TUSCRIPT.
Die Datumsfunktion, allgemeiner Aufruf:
SET wo = DATE (modus, tag, monat, jahr, nummer)
liefert beim modus EASTER zu einem im Argument jahr angegebenen Jahr das
Osterdatum in den Variablen tag und monat. Als Funktionswert erhält man in der
Variablen wo den Wochentag (1 = Montag usw.; bei unmöglichem Datum, z.B. 31.
April, den Wert 0).
Unsere Frage ist gerade umgekehrt: In welchen Jahren fällt Ostern auf den 7.
April? Die Lösung, die wir in einem TUSCRIPT-Skript = Makro unterbringen wollen, ist
überraschend einfach. Zu beachten ist nur noch die Festlegung des Osterdatums
(erster Sonntag nach dem ersten Frühlingsvollmond) durch das Konzil von Nicäa (Mitte 325).
Für frühere Jahre würde der berechnete Ostertermin nicht stimmen.
Wir berechnen also in einer Schleife (LOOP) für alle Jahre zwischen 326
und 2100 (das dürfte meist genügen) den Ostertermin und drucken die Jahre aus,
in denen der Ostersonntag auf den angegebenen Tag fällt.
Zunächst wird das Makro im Programm-Modus in eine leere Datei, z.B. 'prog', geschrieben:
$$! tag, monat $$ MODE TUSCRIPT - Nun für alle Jahre von 326 bis 2100 das Osterdatum berechnen, - prüfen, ob Tag und Monat der Vorgabe entsprechen, dann ausgeben: LOOP jahr = 326, 2100 SET egal = DATE (EASTER,ostag,osmonat,jahr,auchegal) IF (ostag.EQ.tag.AND.osmonat.EQ.monat) PRINT jahr ENDLOOP
Um es bequem aufrufen zu können, speichern wir das Programm in eine Segmentdatei (z.B. 'makrodatei'),
die zuerst eingerichtet und dann als (erste, zweite oder dritte) Makrodatei definiert wird:
#DA,makrodatei #DE,makrodatei (oder #DE,2:makrodatei oder #DE,3:makrodatei)
Nun edieren wir wieder die Datei 'prog' und geben im Editor die RETTE-Anweisung,
mit der wir den Inhalt der Datei 'prog' als Segment 'ostern' in die Segmentdatei abspeichern:
R,makrodatei,ostern
Nun können wir auf Kommandoebene das Makro aufrufen mit
#$ostern,7,4
und erhalten eine Liste von 54 Jahren zwischen 334 und 2080, von denen nur 1697
in das letzte Drittel des 17. Jahrhunderts fällt. (Das ist ein Zufall; andere
Jahre liegen näher beieinander.)
Damit wäre das Problem gelöst, wenn alle Länder der Kalenderreform Papst Gregors
XIII. gefolgt wären. Die evangelischen Länder Deutschlands führten aber erst 1700
den gregorianischen Kalender ein, andere nichtkatholische Staaten verhielten sich
ähnlich, Rußland blieb bis 1917 beim julianischen Kalender. Unser Dokument ist nun
aber in Württemberg geschrieben, also brauchen wir die Jahre, in denen nach
altem Stil, d.h. nach dem julianischen Kalender, Ostern auf den 7. April fällt.
Auch hierfür hat TUSTEP vorgesorgt: Statt EASTER brauchen wir in der Datumsfunktion
nur EASTER/JULIAN anzugeben. Zweckmäßig sehen wir beide Varianten in einem und
demselben Makro vor und erweitern:
$$! tag, monat, stil=neu $$ MODE TUSCRIPT - Nun für alle Jahre von 326 bis 2100 das Osterdatum berechnen, - prüfen, ob Tag und Monat der Vorgabe entsprechen, dann ausgeben: LOOP jahr = 326, 2100 IF (stil.AB."neu") THEN SET egal = DATE (EASTER,ostag,osmonat,jahr,auchegal) ELSEIF (stil.AB."alt","julianisch") THEN SET egal = DATE (EASTER/JULIAN,ostag,osmonat,jahr,auchegal) ELSE PRINT/ERROR "Falsche Angabe ",stil," zur Spezifikation STIL." PRINT/ERROR "Zulässig sind (auch abgekürzt) ALT (gleichwertig" ERROR/STOP "JULIANISCH) und NEU (Voreinstellung)." ENDIF IF (ostag.EQ.tag.AND.osmonat.EQ.monat) PRINT jahr ENDLOOP
Ohne Angabe zu stil erhalten wir mit dem erweiterten Makro natürlich dasselbe
Ergebnis wir mit dem ersten, weil „neu“ voreingestellt ist (1. Zeile).
Mit dem Aufruf
#$ostern,7,4,a
stimmt das Ergebnis bis zum Jahr 1577 mit dem vorigen überein, für die späteren Jahre nicht.
In das letzte Drittel des 17. Jahrhunderts fallen im alten Stil die Jahre 1667 und 1672.
Wir brauchen aber gar nicht die ganze Liste zwischen 326 und 2100 einschließlich,
weil uns nur das letzte Drittel des 17. Jahrhunderts interessiert, also etwa die Jahre von 1660 und 1710.
Also müssen wir die Grenzjahre variabel machen; als Voreinstellung können wir 326 und 2100 beibehalten.
Das Makro sieht dann so aus:
$$! tag, monat, stil=neu, erstjahr=326, letztjahr=2100 $$ MODE TUSCRIPT, {} - ist zu Tag und Monat überhaupt etwas angegeben? IF (tag.EQ.'LEER') ERROR/STOP "Angabe zu TAG fehlt!" IF (monat.EQ.'LEER') ERROR/STOP "Angabe zu MONAT fehlt!" - sind die Angaben zu Tag, Monat, Erstjahr, Letztjahr numerisch? - ("teilw" enthält den Namen der Variablen, z.B. "Monat", "@teilw" - ihren Inhalt, z.B. "4".) SET var = "TAG'MONAT'ERSTJAHR'LETZTJAHR" LOOP teilw = var IF (@teilw.NE.'ZIFFERN') THEN ERROR/STOP "Angabe ",@teilw," zu ",teilw," ist nicht numerisch" ENDIF ENDLOOP - ist die Angabe zu Erstjahr sinnvoll? IF (erstjahr.LT.326) THEN PRINT/ERROR "Erstjahr vor 326 nicht sinnvoll, weil der geltende Oster-" PRINT/ERROR "termin (Sonntag nach dem ersten Frühlingsvollmond) erst" ERROR/STOP "beim Konzil von Nikaia (Mai bis Juli 325) bestimmt wurde." ENDIF - ergeben tag und monat ein mögliches Tagesdatum? SET wtg = DATE (NUMBER,tag,monat,2004,egal) IF (wtg.EQ.0) ERROR/STOP tag,".",monat,". ist kein mögliches Tagesdatum!" - ergeben tag und monat ein mögliches Osterdatum? - frühestes Osterdatum: 22. März, spätestes: 25. April IF (monat.LT.3.OR.monat.GT.4.OR. monat.EQ.3.AND.tag.LT.22.OR. monat.EQ.4.AND.tag.GT.25) THEN PRINT/ERROR "Der ",tag,".",monat,". ist kein mögliches Osterdatum." ERROR/STOP "Frühester Ostertermin: 22. März, spätester: 25. April." ENDIF - Schleife über alle Jahre des Zeitraums erstjahr bis letztjahr: SET treffer = 0, zeile = " ", i = 0 LOOP jahr = erstjahr, letztjahr IF (stil.AB."neu") THEN SET egal = DATE (EASTER,ostag,osmonat,jahr,auchegal) ELSEIF (stil.AB."alt","julianisch") THEN SET egal = DATE (EASTER/JULIAN,ostag,osmonat,jahr,auchegal) ELSE PRINT/ERROR "Falsche Angabe ",stil," zur Spezifikation STIL." PRINT/ERROR "Zulässig sind (auch abgekürzt) ALT (gleichwertig" ERROR/STOP "JULIANISCH) und NEU (Voreinstellung)." ENDIF - Jahre mit dem gesuchten Ostertermin (Treffer) ermitteln, unten mit - CONCAT die Ausgabe in Zeilen zu 10 Jahren abteilen: IF (ostag.EQ.tag.AND.osmonat.EQ.monat) THEN - ausgeben, wenn die Zeile 10 Jahre enthält (PRINT): IF (i.EQ.10) THEN - Jahre unter 1000 durch vorangestelltes Blank vierstellig machen: SET zeile = EXCHANGE (zeile, "| {3}{\0}{]}{0} | {+2=}|") - kleiner Abstand nach 5 Jahren: SET zeile = EXCHANGE (zeile, "| | |", 30, 31) PRINT zeile - nach PRINT Variablen für Ausgabe zurücksetzen: SET i = 0, Zeile = " " ENDIF SET treffer = treffer + 1 SET i = i+1, zeile = CONCAT (zeile," ",jahr) ENDIF ENDLOOP - Meldung, wenn kein Treffer: IF (treffer.EQ.0) THEN PRINT/ERROR "Zwischen ",erstjahr," und ",letztjahr," kein Jahr mit Osterdatum ",tag,".",monat,"." ELSEIF (i.NE.0) THEN SET e = "e" IF (treffer.EQ.1) SET e = "" SET zeile = EXCHANGE (zeile, "| {3}{\0}{]}{0} | {+2=}|") SET zeile = EXCHANGE (zeile, "| | |", 30, 31) - letzte Zeile ausgeben, falls kürzer als 10 Jahre; Endmeldung PRINT zeile SET meldung = " Von {erstjahr} bis {letztjahr} {treffer} Jahr{e} mit Ostertermin {tag}.{monat}." SET meldung = EXCHANGE (meldung,"|.3.|. März.|.4.|. April.|") PRINT "" PRINT meldung ENDIF
Mit dem Aufruf
#$ostern,7,4,a,1660,1710
erhalten wir nun nur noch die Jahre 1667 und 1672.