SF 658405: calendar.py to rely on the datetime module instead of the 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().
This commit is contained in:
Raymond Hettinger 2002-12-25 16:37:19 +00:00
parent 80475bb4d2
commit e11b510a5b
3 changed files with 18 additions and 22 deletions

View File

@ -15,10 +15,12 @@ convention). Use \function{setfirstweekday()} to set the first day of the
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

View File

@ -5,10 +5,7 @@ default, these calendars have Monday as the first day of the week, and
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",
@ -35,7 +32,7 @@ class _localized_month:
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]
@ -49,7 +46,7 @@ class _localized_day:
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]
@ -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
@ -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

View File

@ -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.