Add Python 3.9 into trove classifiers and CI.
1 
# * coding: utf8 *


2  84 
"""

3 
This module offers a generic Easter computing method for any given year, using


4 
Western, Orthodox or Julian algorithms.


5 
"""


6  
7  84 
import datetime 
8  
9  84 
__all__ = ["easter", "EASTER_JULIAN", "EASTER_ORTHODOX", "EASTER_WESTERN"] 
10  
11  84 
EASTER_JULIAN = 1 
12  84 
EASTER_ORTHODOX = 2 
13  84 
EASTER_WESTERN = 3 
14  
15  
16  84 
def easter(year, method=EASTER_WESTERN): 
17 
"""


18 
This method was ported from the work done by GM Arts,


19 
on top of the algorithm by Claus Tondering, which was


20 
based in part on the algorithm of Ouding (1940), as


21 
quoted in "Explanatory Supplement to the Astronomical


22 
Almanac", P. Kenneth Seidelmann, editor.


23  
24 
This algorithm implements three different Easter


25 
calculation methods:


26  
27 
1. Original calculation in Julian calendar, valid in


28 
dates after 326 AD


29 
2. Original method, with date converted to Gregorian


30 
calendar, valid in years 1583 to 4099


31 
3. Revised method, in Gregorian calendar, valid in


32 
years 1583 to 4099 as well


33  
34 
These methods are represented by the constants:


35  
36 
* ``EASTER_JULIAN = 1``


37 
* ``EASTER_ORTHODOX = 2``


38 
* ``EASTER_WESTERN = 3``


39  
40 
The default method is method 3.


41  
42 
More about the algorithm may be found at:


43  
44 
`GM Arts: Easter Algorithms <http://www.gmarts.org/index.php?go=415>`_


45  
46 
and


47  
48 
`The Calendar FAQ: Easter <https://www.tondering.dk/claus/cal/easter.php>`_


49  
50 
"""


51  
52  84 
if not (1 <= method <= 3): 
53  84 
raise ValueError("invalid method") 
54  
55 
# g  Golden year  1


56 
# c  Century


57 
# h  (23  Epact) mod 30


58 
# i  Number of days from March 21 to Paschal Full Moon


59 
# j  Weekday for PFM (0=Sunday, etc)


60 
# p  Number of days from March 21 to Sunday on or before PFM


61 
# (6 to 28 methods 1 & 3, to 56 for method 2)


62 
# e  Extra days to add for method 2 (converting Julian


63 
# date to Gregorian date)


64  
65  84 
y = year 
66  84 
g = y % 19 
67  84 
e = 0 
68  84 
if method < 3: 
69 
# Old method


70  84 
i = (19*g + 15) % 30 
71  84 
j = (y + y//4 + i) % 7 
72  84 
if method == 2: 
73 
# Extra dates to convert Julian to Gregorian date


74  84 
e = 10 
75  84 
if y > 1600: 
76  84 
e = e + y//100  16  (y//100  16)//4 
77 
else: 

78 
# New method


79  84 
c = y//100 
80  84 
h = (c  c//4  (8*c + 13)//25 + 19*g + 15) % 30 
81  84 
i = h  (h//28)*(1  (h//28)*(29//(h + 1))*((21  g)//11)) 
82  84 
j = (y + y//4 + i + 2  c + c//4) % 7 
83  
84 
# p can be from 6 to 56 corresponding to dates 22 March to 23 May


85 
# (later dates apply to method 2, although 23 May never actually occurs)


86  84 
p = i  j + e 
87  84 
d = 1 + (p + 27 + (p + 6)//40) % 31 
88  84 
m = 3 + (p + 26)//30 
89  84 
return datetime.date(int(y), int(m), int(d)) 
Read our documentation on viewing source code .