mirror of
https://github.com/python/cpython.git
synced 2025-09-19 07:00:59 +00:00
Issue #9151: Demo/classes/Dates.py does not work in 3.x Converted
descriptive comment into a docstring. Cast attributes to int in __init__. Use __new__ instead of deleting attributes to "uninitialize".
This commit is contained in:
parent
2cf1585499
commit
401d856309
1 changed files with 45 additions and 46 deletions
|
@ -1,43 +1,45 @@
|
||||||
# Class Date supplies date objects that support date arithmetic.
|
"""
|
||||||
#
|
Class Date supplies date objects that support date arithmetic.
|
||||||
# Date(month,day,year) returns a Date object. An instance prints as,
|
|
||||||
# e.g., 'Mon 16 Aug 1993'.
|
|
||||||
#
|
|
||||||
# Addition, subtraction, comparison operators, min, max, and sorting
|
|
||||||
# all work as expected for date objects: int+date or date+int returns
|
|
||||||
# the date `int' days from `date'; date+date raises an exception;
|
|
||||||
# date-int returns the date `int' days before `date'; date2-date1 returns
|
|
||||||
# an integer, the number of days from date1 to date2; int-date raises an
|
|
||||||
# exception; date1 < date2 is true iff date1 occurs before date2 (&
|
|
||||||
# similarly for other comparisons); min(date1,date2) is the earlier of
|
|
||||||
# the two dates and max(date1,date2) the later; and date objects can be
|
|
||||||
# used as dictionary keys.
|
|
||||||
#
|
|
||||||
# Date objects support one visible method, date.weekday(). This returns
|
|
||||||
# the day of the week the date falls on, as a string.
|
|
||||||
#
|
|
||||||
# Date objects also have 4 read-only data attributes:
|
|
||||||
# .month in 1..12
|
|
||||||
# .day in 1..31
|
|
||||||
# .year int or long int
|
|
||||||
# .ord the ordinal of the date relative to an arbitrary staring point
|
|
||||||
#
|
|
||||||
# The Dates module also supplies function today(), which returns the
|
|
||||||
# current date as a date object.
|
|
||||||
#
|
|
||||||
# Those entranced by calendar trivia will be disappointed, as no attempt
|
|
||||||
# has been made to accommodate the Julian (etc) system. On the other
|
|
||||||
# hand, at least this package knows that 2000 is a leap year but 2100
|
|
||||||
# isn't, and works fine for years with a hundred decimal digits <wink>.
|
|
||||||
|
|
||||||
# Tim Peters tim@ksr.com
|
Date(month,day,year) returns a Date object. An instance prints as,
|
||||||
# not speaking for Kendall Square Research Corp
|
e.g., 'Mon 16 Aug 1993'.
|
||||||
|
|
||||||
# Adapted to Python 1.1 (where some hacks to overcome coercion are unnecessary)
|
Addition, subtraction, comparison operators, min, max, and sorting
|
||||||
# by Guido van Rossum
|
all work as expected for date objects: int+date or date+int returns
|
||||||
|
the date `int' days from `date'; date+date raises an exception;
|
||||||
|
date-int returns the date `int' days before `date'; date2-date1 returns
|
||||||
|
an integer, the number of days from date1 to date2; int-date raises an
|
||||||
|
exception; date1 < date2 is true iff date1 occurs before date2 (&
|
||||||
|
similarly for other comparisons); min(date1,date2) is the earlier of
|
||||||
|
the two dates and max(date1,date2) the later; and date objects can be
|
||||||
|
used as dictionary keys.
|
||||||
|
|
||||||
# Note that as of Python 2.3, a datetime module is included in the stardard
|
Date objects support one visible method, date.weekday(). This returns
|
||||||
# library.
|
the day of the week the date falls on, as a string.
|
||||||
|
|
||||||
|
Date objects also have 4 read-only data attributes:
|
||||||
|
.month in 1..12
|
||||||
|
.day in 1..31
|
||||||
|
.year int or long int
|
||||||
|
.ord the ordinal of the date relative to an arbitrary staring point
|
||||||
|
|
||||||
|
The Dates module also supplies function today(), which returns the
|
||||||
|
current date as a date object.
|
||||||
|
|
||||||
|
Those entranced by calendar trivia will be disappointed, as no attempt
|
||||||
|
has been made to accommodate the Julian (etc) system. On the other
|
||||||
|
hand, at least this package knows that 2000 is a leap year but 2100
|
||||||
|
isn't, and works fine for years with a hundred decimal digits <wink>.
|
||||||
|
|
||||||
|
Tim Peters tim@ksr.com
|
||||||
|
not speaking for Kendall Square Research Corp
|
||||||
|
|
||||||
|
Adapted to Python 1.1 (where some hacks to overcome coercion are unnecessary)
|
||||||
|
by Guido van Rossum
|
||||||
|
|
||||||
|
Note that as of Python 2.3, a datetime module is included in the stardard
|
||||||
|
library.
|
||||||
|
"""
|
||||||
|
|
||||||
import functools
|
import functools
|
||||||
|
|
||||||
|
@ -86,8 +88,9 @@ def _num2date(n): # return date with ordinal n
|
||||||
if not isinstance(n, int):
|
if not isinstance(n, int):
|
||||||
raise TypeError('argument must be integer: %r' % type(n))
|
raise TypeError('argument must be integer: %r' % type(n))
|
||||||
|
|
||||||
ans = Date(1,1,1) # arguments irrelevant; just getting a Date obj
|
# Get uninitialized Date object. This is necesary because once
|
||||||
del ans.ord, ans.month, ans.day, ans.year # un-initialize it
|
# attributes are set, they cannot be changed.
|
||||||
|
ans = Date.__new__(Date)
|
||||||
ans.ord = n
|
ans.ord = n
|
||||||
|
|
||||||
n400 = (n-1)//_DI400Y # # of 400-year blocks preceding
|
n400 = (n-1)//_DI400Y # # of 400-year blocks preceding
|
||||||
|
@ -97,11 +100,7 @@ def _num2date(n): # return date with ordinal n
|
||||||
if dby >= n:
|
if dby >= n:
|
||||||
more = more - 1
|
more = more - 1
|
||||||
dby = dby - _days_in_year(more)
|
dby = dby - _days_in_year(more)
|
||||||
year, n = year + more, int(n - dby)
|
year, n = year + more, n - dby
|
||||||
|
|
||||||
try: year = int(year) # chop to int, if it fits
|
|
||||||
except (ValueError, OverflowError): pass
|
|
||||||
|
|
||||||
month = min(n//29 + 1, 12)
|
month = min(n//29 + 1, 12)
|
||||||
dbm = _days_before_month(month, year)
|
dbm = _days_before_month(month, year)
|
||||||
if dbm >= n:
|
if dbm >= n:
|
||||||
|
@ -112,7 +111,7 @@ def _num2date(n): # return date with ordinal n
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
def _num2day(n): # return weekday name of day with ordinal n
|
def _num2day(n): # return weekday name of day with ordinal n
|
||||||
return _DAY_NAMES[ int(n % 7) ]
|
return _DAY_NAMES[n % 7]
|
||||||
|
|
||||||
@functools.total_ordering
|
@functools.total_ordering
|
||||||
class Date:
|
class Date:
|
||||||
|
@ -122,7 +121,7 @@ class Date:
|
||||||
dim = _days_in_month(month, year)
|
dim = _days_in_month(month, year)
|
||||||
if not 1 <= day <= dim:
|
if not 1 <= day <= dim:
|
||||||
raise ValueError('day must be in 1..%r: %r' % (dim, day))
|
raise ValueError('day must be in 1..%r: %r' % (dim, day))
|
||||||
self.month, self.day, self.year = month, day, year
|
self.month, self.day, self.year = map(int, (month, day, year))
|
||||||
self.ord = _date2num(self)
|
self.ord = _date2num(self)
|
||||||
|
|
||||||
# don't allow setting existing attributes
|
# don't allow setting existing attributes
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue