root/django/trunk/contrib/dateutil/easter.py

Revision 84, 2.5 kB (checked in by steadicat, 15 months ago)

Added loads of useful contrib.

  • Property svn:keywords set to Id
Line 
1"""
2Copyright (c) 2003-2005  Gustavo Niemeyer <gustavo@niemeyer.net>
3
4This module offers extensions to the standard python 2.3+
5datetime module.
6"""
7__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>"
8__license__ = "PSF License"
9
10import datetime
11
12__all__ = ["easter", "EASTER_JULIAN", "EASTER_ORTHODOX", "EASTER_WESTERN"]
13
14EASTER_JULIAN   = 1
15EASTER_ORTHODOX = 2
16EASTER_WESTERN  = 3
17
18def 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(y,m,d)
Note: See TracBrowser for help on using the browser.