12-24-2005, 12:35 AM
Quote:Good to know it...I have never used a formula from that FAQ
For easter i use a snippet i found at the ABC packets, it seems to give good results:
Code:DEFINT A-Z
SUB EaSun (Year, Month, Day) ' Finds month and day of Easter Sunday
J = Year MOD 19
K = Year \ 100
L = Year MOD 100
M = K \ 4
N = K MOD 4
O = L \ 4
P = L MOD 4
Q = (8 * K + 13) \ 25
R = (19 * J + K - M - Q + 15) MOD 30
S = (J + 11 * R) \ 319
T = (2 * (N + O) - P - R + S + 32) MOD 7
U = R - S + T
Month = (U + 90) \ 25
Day = (U + Month + 19) MOD 32
END SUB
Excellent algorithm, Antoni.
I wrote a little program to test it against Knuth's algorithm for 1000 years from 1900 to 2899. It gives exactly the same results.
Knuth's algorithm is a little more complicated since it handles up to 5 digit years.
Anyway, here's my adaptation of Knuth's algorithm including his original comments explaining the cryptic variables. It's been working for me for over 10 years.
Code:
' ========================= EASTER ============================================
' Computes Gregorian Calendar date of Easter Sunday for a given input year.
' Acknowledgement and thanks to Donald E. Knuth.
' Ref: The Art of Computer Programming, Volume 1 Fundamental Algorithms, 1.3.2.
' Knuth's algorithm was implemented as such, with no enhancements.
' According to Knuth, this logic will work up to a 5 digit year.
' This logic has been tested up to the year 9999.
' The resultant Easter dates have been verified for years 1901 through 2100.
' =============================================================================
FUNCTION Easter$ (YYYY) STATIC
REM *
REM *** COMPUTE DATE OF EASTER SUNDAY FOR GIVEN YEAR.
REM *
REM * INPUT: YYYY assumed to be a 4 digit year (max 9999)
REM *
REM * OUTPUT: a date string formatted as YYYYMMDD.
REM *
REM * USAGE: E$ = EASTER$(YYYY)
'* All variables are set to LONG to handle arithmetic
'* for large year numbers.
DIM Y AS LONG
DIM G AS LONG
DIM C AS LONG
DIM X AS LONG
DIM Z AS LONG
DIM D AS LONG
DIM E AS LONG
DIM TEMP AS LONG
DIM N AS LONG
Y = YYYY '* Force year as long
'* Compute "golden number" of the year in the 19-year Metonic cycle.
G = (Y mod 19) + 1
'* Compute the Century. Note: When Y is not multiple of 100,
'* C is the century number.
C = INT(Y/100) + 1
'* Corrections:
'* X is number of years, like 1900, in which leap year was dropped
'* in order to keep in step with the sun.
'* Z is special correction to sync Easter with the moon's orbit.
X = INT(3*C/4) - 12
Z = INT((8*C + 5) / 25) - 5
'* Find Sunday
D = INT(5*Y/4) - X - 10
'* Compute so-called Epact, which specifies when a full moon occurs.
TEMP = (11*G + 20 + Z - X)
E = TEMP-30*INT(TEMP/30) 'Same as TEMP MOD 30 but works for negative TEMP.
if (E=25 and G>11) or E=24 then E=E+1
'* Find full moon. Easter is the 1st Sunday after the 1st full moon
'* which occurs on or after March 21st.
'* This is a "calendar moon" not actual moon.
N = 44 - E
if N<21 then N=N+30
'* Advance to Sunday.
N = N + 7 - ( (D+N) mod 7 )
'* Get Month.
'* N is the day.
if N>31 then
zmm=4 'April
N=N-31
else
zmm=3 'March
end if
'* Pack Easter date as YYYYMMDD
Easter$=FILLSTRING$((Y),4)+FILLSTRING$((zmm),2)+FILLSTRING$((N),2)
END FUNCTION
' ========================= FILLSTRING =============================
' Converts a value to string of specified length with leading zeros.
' ==================================================================
FUNCTION FillString$ (V#,ZL) STATIC
FILLSTRING$=right$(STRING$(ZL,"0")+LTRIM$(STR$(V#)),ZL)
END FUNCTION