Montag, 19. Mai 2008

Datumsspielereien (Teil 1) / Date gadgets (Part 1)

Als ich mit dem Entwickeln von Software begann, hätte ich mir nicht träumen lassen, welche Algorithmen hinter der Berechnung eines speziellen Datums liegen können.

Natürlich war ich mir der beweglichen kirchlichen Feiertage bewußt, aber um das Warum machte ich mir keine Gedanken. Erst wenn wir uns näher mit diesen diversen Feiertagen befassen stellen wir fest, dass das Osterfest für die Berechnung des Fastnachtstermins ebenso ursächliche Wirkung zeigt wie für Christi Himmelfahrt und Pfingsten.

Mit diesem Posting beginne ich eine kleine Serie rund um Datumsberechnungen im Fux. Die Berechnung der Feiertage beruht hierbei auf den Daten der westlichen Kirchen.

Den Anfang macht natürlich das schon zuvor angesprochene Osterfest, im speziellen der Ostersonntag.

Die von Carl Friedrich Gauß erstmals im Jahre 1800 veröffentlichte Gaußsche Osterformel steht bereits in Pascal und Basic und sicherlich auch anderen Sprachen im WWW zum Herunterladen bereit. Der folgende Code stellt eine Möglichkeit der Umsetzung in Visual Foxpro dar.

FUNCTION GetOstersonntag as Date
LPARAMETERS Jahr as Integer
* Erster Sonntag nach dem Frühlingsvollmond                         
* Die u.a. Formel entspricht der von Gauss entwickelten Variante 
LOCAL a as Integer, b as Integer, c as Integer, d as Integer, e as Integer, f as Integer 
    Jahr = SetYear(Jahr) 
    a = MOD(Jahr,19) 
    b = INT(Jahr/ 100) 
    c = INT((8 * b + 13) / 25 - 2) 
    d = b - INT(Jahr/ 400) - 2 
    e = MOD(19 * MOD(Jahr,19) + MOD(15 - c + d,30),30) 
    DO CASE 
    CASE e = 28 AND a > 10
        e = 27 
    CASE e = 29
        e = 28 
    ENDCASE 
    f = MOD(d + 6 * e + 2 * MOD(Jahr,4) + 4 * MOD(Jahr,7) + 6,7) 
    * CTOD entsporgt = korrigierte wOOdy-Version (Thanx :-) )     
    * die '-1' lasse ich im Gedenken an das Original (d + e + 22) 
    * noch so stehen.                                             
    RETURN DATE(Jahr,3,1) + (e + f + 22) - 1
ENDFUNC

Die o.a. Funktion greift auf eine weitere Funktion mit dem Namen 'SetYear' zurück. Sie stellt sicher, dass bei ungültiger Parametrisierung mit einem gültigen Wert gearbeitet wird.

Hier nun diese zusätzliche Funktion, auf die im Übrigen auch die Codebeispiele in den folgenden Postings zurückgreifen werden.

FUNCTION SetYear as Integer
LPARAMETERS Jahr as Integer

    * korrigierte wOOdy-Version (again Thanx :-) )
    RETURN EVL(Jahr, YEAR(DATE()))
   
ENDFUNC

2 Kommentare:

  1. Hi Tom,

    Deine SetYear() Funktion, die du da so aufrufst:

    Jahr = SetYear(Jahr)

    kannste im Normalfall durch das hier ersetzen:

    Jahr = EVL(Jahr, YEAR(DATE()))

    EVL() ist ideal, um optionale Parameter vorzubelegen. Die intern verwendete EMPTY() behandelt ein .F., "" und 0 als leeren Wert, und daher kann man damit wunderbar die benötigten ParamWerte nachlegen, ohne grossartig auf den Typ zu achten.

    AntwortenLöschen
  2. Uhm... Ein hab ich noch: ;)

    Die Rückgabe geht auch noch etwas optimierter: Anstelle von
    RETURN CTOD([01.03.] + PADL(Jahr,4,[0])) + (e + f + 22) - 1

    machste besser ein:
    RETURN DATE(Jahr,3,1) +e+f+21

    wOOdy

    AntwortenLöschen