OLD | NEW |
(Empty) | |
| 1 """ |
| 2 Copyright (c) 2003-2007 Gustavo Niemeyer <gustavo@niemeyer.net> |
| 3 |
| 4 This module offers extensions to the standard python 2.3+ |
| 5 datetime module. |
| 6 """ |
| 7 __author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>" |
| 8 __license__ = "PSF License" |
| 9 |
| 10 import datetime |
| 11 |
| 12 __all__ = ["easter", "EASTER_JULIAN", "EASTER_ORTHODOX", "EASTER_WESTERN"] |
| 13 |
| 14 EASTER_JULIAN = 1 |
| 15 EASTER_ORTHODOX = 2 |
| 16 EASTER_WESTERN = 3 |
| 17 |
| 18 def easter(year, method=EASTER_WESTERN): |
| 19 """ |
| 20 This method was ported from the work done by GM Arts, |
| 21 on top of the algorithm by Claus Tondering, which was |
| 22 based in part on the algorithm of Ouding (1940), as |
| 23 quoted in "Explanatory Supplement to the Astronomical |
| 24 Almanac", P. Kenneth Seidelmann, editor. |
| 25 |
| 26 This algorithm implements three different easter |
| 27 calculation methods: |
| 28 |
| 29 1 - Original calculation in Julian calendar, valid in |
| 30 dates after 326 AD |
| 31 2 - Original method, with date converted to Gregorian |
| 32 calendar, valid in years 1583 to 4099 |
| 33 3 - Revised method, in Gregorian calendar, valid in |
| 34 years 1583 to 4099 as well |
| 35 |
| 36 These methods are represented by the constants: |
| 37 |
| 38 EASTER_JULIAN = 1 |
| 39 EASTER_ORTHODOX = 2 |
| 40 EASTER_WESTERN = 3 |
| 41 |
| 42 The default method is method 3. |
| 43 |
| 44 More about the algorithm may be found at: |
| 45 |
| 46 http://users.chariot.net.au/~gmarts/eastalg.htm |
| 47 |
| 48 and |
| 49 |
| 50 http://www.tondering.dk/claus/calendar.html |
| 51 |
| 52 """ |
| 53 |
| 54 if not (1 <= method <= 3): |
| 55 raise ValueError, "invalid method" |
| 56 |
| 57 # g - Golden year - 1 |
| 58 # c - Century |
| 59 # h - (23 - Epact) mod 30 |
| 60 # i - Number of days from March 21 to Paschal Full Moon |
| 61 # j - Weekday for PFM (0=Sunday, etc) |
| 62 # p - Number of days from March 21 to Sunday on or before PFM |
| 63 # (-6 to 28 methods 1 & 3, to 56 for method 2) |
| 64 # e - Extra days to add for method 2 (converting Julian |
| 65 # date to Gregorian date) |
| 66 |
| 67 y = year |
| 68 g = y % 19 |
| 69 e = 0 |
| 70 if method < 3: |
| 71 # Old method |
| 72 i = (19*g+15)%30 |
| 73 j = (y+y//4+i)%7 |
| 74 if method == 2: |
| 75 # Extra dates to convert Julian to Gregorian date |
| 76 e = 10 |
| 77 if y > 1600: |
| 78 e = e+y//100-16-(y//100-16)//4 |
| 79 else: |
| 80 # New method |
| 81 c = y//100 |
| 82 h = (c-c//4-(8*c+13)//25+19*g+15)%30 |
| 83 i = h-(h//28)*(1-(h//28)*(29//(h+1))*((21-g)//11)) |
| 84 j = (y+y//4+i+2-c+c//4)%7 |
| 85 |
| 86 # p can be from -6 to 56 corresponding to dates 22 March to 23 May |
| 87 # (later dates apply to method 2, although 23 May never actually occurs) |
| 88 p = i-j+e |
| 89 d = 1+(p+27+(p+6)//40)%31 |
| 90 m = 3+(p+26)//30 |
| 91 return datetime.date(int(y),int(m),int(d)) |
| 92 |
OLD | NEW |