Buchempfehlung
MySQL kurz & gut
MySQL kurz & gut
Das preiswerte Taschen- buch stellt MySQL-rele- vante Inhalte systematisch und knapp dar, sodass es sich optimal zum Nach- schlagen beim Pro- grammieren eignet. [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

Code-Beispiel

Code-Beispiele » Mathematik

Osterdatums-Berechnung

Lizenz:Erster Autor:Letzte Bearbeitung:
k. A.Redakteurytwinky 01.05.2012

Die Berechnung des Osterdatums ist die Grundlage für die Berechnung der beweglichen Feiertage in einem Jahr.
Rechenwege gibt es mehrere..
Roland Chastain hat Externer Link!hier den Algo von Oudin vorgestellt.
Ich habe diesen mal mit dem von Lichtenberg verglichen und außer Konkurrenz noch den von Gauss dazugetan..
..außer Konkurrenz deshalb, weil der Algo von Gauss erst durch die Bearbeitung von Lichtenberg alle Daten richtig liefert.
In der neuen Programmversion ist noch die 'Osterformel von ytwinky' dazugekommen.Sie hat den Vorteil, daß nur noch 2 Variablen berechnet werden müssen, aber auch den Nachteil, die 'langsamste' Formel zu sein. Doch durch ihre Entwicklung wurde der Algo von Lichtenberg schneller als der von Gauss. Der Rest steht im Programm

'Easterformula by Lichtenberg:
'                         K(X)          = X div 100                                   (1)
'                         M(K)          = 15 + (3K + 3) div 4 - (8K + 13) div 25      (2)
'                         S(K)          = 2 - (3K + 3) div 4                          (3)
'Gaussian cyclenumber A(X)          = X mod 19                                    (4)
'Moo#ndifference          D(A,M)        = (19A + M) mod 30                            (5)
'                         R(D,A)        = D div 29 + (D div 28 - D div 29)(A div 11)  (6)
'                         OG(D,R)   = 21 + D - R                                  (7)
'                         SZ(X,S)   = 7 - (X + X div 4 + S) mod 7                 (8)
'Easterdifference         OE(OG,SZ) = 7 - (OG - SZ) mod 7                         (9)
'Eastersunday             OS                = (OG + OE) of march                         (10)
'                         OS                = 32 is 1st april and so on..
'Remarks: OS means a 'monthday in march'.
'         i.e, if OS >31 then eastersunday is not in march but in april so subtract 31
'         and add 1 for month
'There is not much we can do to simplify this formula:
'OE and SZ don't have to be stored in variables..
'10. OS=(OG + 7 - (OG - 7 - (X + X div 4 + S) mod 7) mod 7)
'This would eliminate 2 integer-variables, but the operations will still have
'to be done and the algorithm would be more complex.
'use variable-initialization..
'
Function GEaster(X As Integer) As Integer 'Gauss* formula is not always correct but that's his fault ;-))
    Var d=0, k=X\100, p=(8*k+13)\25, q=k\4, M=(15+k-q-p) mod 30, N=(4+k-q) mod 7
    d=(19*(X mod 19)+M) mod 30
    Return (22+d+(2*(X mod 4)+4*(X mod 7)+6*d+N) mod 7) 'eastersunday as 'day in march'
End Function

Function LEaster(X As Integer) As Integer 'Lichtenberg improved the Gaussian formula, www.gidf.de
    Var A=X Mod 19, K=X\100, Z=(3*K+3)\4, M=15+Z-(8*K+13)\25, D=(19*A+M) Mod 30, B=D/29, OG=21+D-(B+(D\28-B)*(A\11))
    Return (OG+7-(OG-(7-(X+X\4+2-Z) Mod 7)) Mod 7) 'eastersunday as 'day in march'
End Function 'this way Lichtenberg is ~as fast as oudin..

Function OEaster(ByRef J As Integer) As Integer 'Algorithm of Oudin modified by ytwinky
  Dim As uShort G=J-19*(J\19), C=J\100, C4=C-C\4, E=(8*C+13)\25, H, K, PQ, I, B, J1, R
  H=19*G+C4-E+15-30*((19*G+C4-E+15)\30)
  K=H\28
  I=(K*(29\(H+1)*(21-G)\11)-1)*K+H
  J1=J+J\4+I+2-C4
    Return 28+I-(J1-7*(J1\7)) 'eastersunday as 'day in march'
End Function

Function yEaster(X As Integer) As Integer 'ytwinky's formula:mathematically reduced to D and OG..
    Var D=((19*(X Mod 19)+15+(3*(X\100)+3)\4-(8*(X\100)+13)\25) MOD 30)
    Var OG=21+D-(D\29+(D\28-D\29)*((X Mod 19)\11))
    Return OG+(7-((OG-(7-((X+X\4+2-((3*(X\100)+3)\4)) MOD 7))) MOD 7)) 'eastersunday as 'day in march'
End Function '..but alas, it is the 'slowest'.. ;-))

Function PrDate(OS As Integer, Lng As String="en") As String
    Var s="", EasterSunday=IIf(OS>31, OS-31, OS)
    Select Case lcase(Lng)
        Case "de" 'german
            s =Str(EasterSunday) &". " & *IIf(OS>31, @"April", @"M„rz")
        Case "en" 'english
            s = *IIf(OS>31, @"april", @"march") &", " & EasterSunday
        Case Else
'   s &= *IIf(OS>31, @"4th MonthOfYear", @"3rd MonthOfYear") 'insert your monthnames here..
' combine EasterSunday with Monthname and a separator of your choice..
    End Select
    Return s
End Function

Var Current=Cast(Integer, Right(Date, 4)), i=0, os=0, startyear=0, stopyear=0, starttime=0.0, stoptime=0.0
Input "Start in year:", startyear
Input "Stop in year:", stopyear
If startyear=0 Then startyear=Current
If stopyear=0 Or stopyear<startyear Then stopyear=startyear

Print "Show that the GAUSS-formula gives 'different' results(taken from Wiki).."
Print "Year" &!"\tGauss*    \tLichtenberg    \tOudin    \tytwinky"
Print 1954 &!"\t" &PrDate(GEaster(1954)) &!"\t" &PrDate(LEaster(1954)) &!"\t" &PrDate(OEaster(1954)) &!"\t" &PrDate(yEaster(1954))
Print 1981 &!"\t" &PrDate(GEaster(1981)) &!"\t" &PrDate(LEaster(1981)) &!"\t" &PrDate(OEaster(1981)) &!"\t" &PrDate(yEaster(1981))
For i=startyear To stopyear
    Print i &!"\t" &PrDate(GEaster(i)) &!"\t" &PrDate(LEaster(i)) &!"\t" &PrDate(OEaster(i)) &!"\t" &PrDate(yEaster(i))
Next
Print "This is no tutorial to show you how to save the results.. *rofl*"
Startyear=1700
Stopyear=4700
Print "Compute Eastersundays from " &StartYear &" to " &StopYear &".."
StartTime=Timer
For i=StartYear To StopYear
    os=GEaster(i)
Next
StopTime=Timer
Print Using "Gauss:       #.####*"; (StopTime-StartTime)
StartTime=Timer
For i=StartYear To StopYear
    os=LEaster(i)
Next
StopTime=Timer
Print Using "Lichtenberg: #.####"; (StopTime-StartTime)
StartTime=Timer
For i=StartYear To StopYear
    os=OEaster(i)
Next
StopTime=Timer
Print Using "Oudin:       #.####"; (StopTime-StartTime)
StartTime=Timer
For i=StartYear To StopYear
    os=yEaster(i)
Next
StopTime=Timer
Print Using "ytwinky:     #.####"; (StopTime-StartTime);
GetKey

Viel Spaß beim Listenerstellen oder Zeitvergleichen
Gruß
ytwinky


Zusätzliche Informationen und Funktionen
  • Das Code-Beispiel wurde am 27.04.2012 von Redakteurytwinky angelegt.
  • Die aktuellste Version wurde am 01.05.2012 von Redakteurytwinky gespeichert.
  Bearbeiten Bearbeiten  

  Versionen Versionen