Skip to content

Commit

Permalink
SF 658405: calendar.py to rely on the datetime module instead of the …
Browse files Browse the repository at this point in the history
…time

module.

The code is shorter, more readable, faster, and dramatically increases the
range of acceptable dates.

Also, used the floor division operator in leapdays().
  • Loading branch information
rhettinger committed Dec 25, 2002
1 parent 80475bb commit e11b510
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 22 deletions.
10 changes: 6 additions & 4 deletions Doc/lib/libcalendar.tex
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ \section{\module{calendar} ---
week to Sunday (6) or to any other weekday. Parameters that specify
dates are given as integers.

Most of these functions rely on the platform provided \function{mktime()}.
Therefore, valid argument values may vary from system to system.
On Unix, valid years are typically between \code{1970} and \code{2037},
but may be work between \code{1902} and \code{2037}.
Most of these functions rely on the \module{datetime} module which
uses an idealized calendar, the current Gregorian calendar indefinitely
extended in both directions. This matches the definition of the
"proleptic Gregorian" calendar in Dershowitz and Reingold's book
"Calendrical Calculations", where it's the base calendar for all
computations.

\begin{funcdesc}{setfirstweekday}{weekday}
Sets the weekday (\code{0} is Monday, \code{6} is Sunday) to start
Expand Down
26 changes: 8 additions & 18 deletions Lib/calendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@
Sunday as the last (the European convention). Use setfirstweekday() to
set the first day of the week (0=Monday, 6=Sunday)."""

# Revision 2: uses functions from built-in time module

# Import functions and variables from time module
from time import localtime, mktime, strftime
import datetime

__all__ = ["error","setfirstweekday","firstweekday","isleap",
"leapdays","weekday","monthrange","monthcalendar",
Expand All @@ -35,7 +32,7 @@ def __init__(self, format):
self.format = format

def __getitem__(self, i):
data = [strftime(self.format, (2001, j, 1, 12, 0, 0, 1, 1, 0))
data = [datetime.date(2001, j, 1).strftime(self.format)
for j in range(1, 13)]
data.insert(0, "")
return data[i]
Expand All @@ -49,7 +46,7 @@ def __init__(self, format):

def __getitem__(self, i):
# January 1, 2001, was a Monday.
data = [strftime(self.format, (2001, 1, j+1, 12, 0, 0, j, j+1, 0))
data = [datetime.date(2001, 1, j+1).strftime(self.format)
for j in range(7)]
return data[i]

Expand Down Expand Up @@ -89,14 +86,12 @@ def leapdays(y1, y2):
Assume y1 <= y2."""
y1 -= 1
y2 -= 1
return (y2/4 - y1/4) - (y2/100 - y1/100) + (y2/400 - y1/400)
return (y2//4 - y1//4) - (y2//100 - y1//100) + (y2//400 - y1//400)

def weekday(year, month, day):
"""Return weekday (0-6 ~ Mon-Sun) for year (1970-...), month (1-12),
day (1-31)."""
secs = mktime((year, month, day, 0, 0, 0, 0, 0, 0))
tuple = localtime(secs)
return tuple[6]
return datetime.date(year, month, day).weekday()

def monthrange(year, month):
"""Return weekday (0-6 ~ Mon-Sun) and number of days (28-31) for
Expand Down Expand Up @@ -213,17 +208,12 @@ def calendar(year, w=0, l=0, c=_spacing):
return s[:-l] + '\n'

EPOCH = 1970
_EPOCH_ORD = datetime.date(EPOCH, 1, 1).toordinal()

def timegm(tuple):
"""Unrelated but handy function to calculate Unix timestamp from GMT."""
year, month, day, hour, minute, second = tuple[:6]
assert year >= EPOCH
assert 1 <= month <= 12
days = 365*(year-EPOCH) + leapdays(EPOCH, year)
for i in range(1, month):
days = days + mdays[i]
if month > 2 and isleap(year):
days = days + 1
days = days + day - 1
days = datetime.date(year, month, day).toordinal() - _EPOCH_ORD
hours = days*24 + hour
minutes = hours*60 + minute
seconds = minutes*60 + second
Expand Down
4 changes: 4 additions & 0 deletions Misc/NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,10 @@ Extension modules
Library
-------

- calendar.py now depends on the new datetime module rather than
the time module. As a result, the range of allowable dates
has been increased.

- pdb has a new 'j(ump)' command to select the next line to be
executed.

Expand Down

0 comments on commit e11b510

Please sign in to comment.