Zurück zum Inhaltsverzeichnis - Lösungen und Tipps


Erstellen eines immerwährenden Kalenders

- [ 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.


Jahre mit bestimmtem Osterdatum errechnen

- [ 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.


Zurück zum Inhaltsverzeichnis - Lösungen und Tipps