Code-Beispiel
Osterdatums-Berechnung
Lizenz: | Erster Autor: | Letzte Bearbeitung: |
k. A. | ytwinky | 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 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 ytwinky angelegt.
- Die aktuellste Version wurde am 01.05.2012 von ytwinky gespeichert.
|
|