[[tuscript:loesungen:start|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. \\ \\ {{files_open:daten:kalendermak.tf|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 [[tustep:loesungen:rechnen|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:**\\ * **Kopieren Sie das Skript** in eine TUSTEP-Datei, z.B. 'ostern.tf". * **Starten Sie das Makro** mit dem Kommando #$?$ostern.tf und geben Sie das gewünschte Osterdatum an * **Beispiel** für Jahre, in denen Ostern auf den **7. April** fiel/fällt: #$?$ostern.tf,7,4 * **Erweiterte Angabe**, wenn der **alte Stil** zugrunde gelegt werden soll: #$?$ostern.tf,7,4,a * **Erweiterte Angabe**, wenn der **Zeitraum** (z.B. Jahre zwischen 1660 und 1700) eingeschränkt werden soll: #$?$ostern.tf,7,4,a,1660,1700 * Die betreffenden Jahre werden auf den Bildschirm ausgegeben. $$- 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: \\ \\ {{files_open:daten:kalendermak.tf|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. ---- [[tuscript:loesungen:start|Zurück zum Inhaltsverzeichnis - Lösungen und Tipps]]