Update of /cvsroot/python/python/nondist/sandbox/datetime In directory usw-pr-cvs1:/tmp/cvs-serv1524 Modified Files: datetime.py test_datetime.py Log Message: Incorporate a pile of utility functions from Demo/classes/Dates.py, which also assumes the Gregorian calender indefinitely extended. In particular, this gives us _date2num() and _num2date() utilities that establish a bijection between datetime objects and a contiguous range of integers, such that consecutive days are associated with consecutive integers. Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** datetime.py 1 Mar 2002 22:19:41 -0000 1.3 --- datetime.py 1 Mar 2002 22:42:28 -0000 1.4 *************** *** 4,7 **** --- 4,75 ---- MAXYEAR = 9999 # XXX The design doc says 65535 + # Utility functions, adapted from Python's Demo/classes/Dates.py, which + # also assumes the current Gregorian calendar indefinitely extended in + # both directions. + + _DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] + + _DAYS_BEFORE_MONTH = [] + dbm = 0 + for dim in _DAYS_IN_MONTH: + _DAYS_BEFORE_MONTH.append(dbm) + dbm = dbm + dim + del dbm, dim + + def _is_leap(year): + "year -> 1 if leap year, else 0." + return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0) + + def _days_in_year(year): + "year -> number of days in year (366 if a leap year, else 365)." + return 365 + _is_leap(year) + + def _days_before_year(year): + "year -> number of days before January 1st of year." + return year*365 + (year+3)//4 - (year+99)//100 + (year+399)//400 + + def _days_in_month(month, year): + "month, year -> number of days in that month in that year." + assert 1 <= month <= 12, month + if month == 2 and _is_leap(year): + return 29 + return _DAYS_IN_MONTH[month-1] + + def _days_before_month(month, year): + "month, year -> number of days in year preceeding first day of month." + return _DAYS_BEFORE_MONTH[month-1] + (month > 2 and _is_leap(year)) + + def _date2num(date): + "datetime object -> day ordinal, considering 01-Jan-0000 as day 1." + assert isinstance(date, datetime) + return (_days_before_year(date.year) + + _days_before_month(date.month, date.year) + + date.day) + + _DI400Y = _days_before_year(400) # number of days in 400 years + + def _num2date(n): + "day ordinal -> datetime object." + + n400 = (n-1) // _DI400Y # number of 400-year blocks preceding + year = n400 * 400 + n -= n400 * _DI400Y + + more = n // 365 + dby = _days_before_year(more) + if dby >= n: + more -= 1 + dby -= _days_in_year(more) + year += more + n -= dby + + month = min(n//29 + 1, 12) + dbm = _days_before_month(month, year) + if dbm >= n: + month -= 1 + dbm -= _days_in_month(month, year) + + return datetime(year, month, n-dbm) + class basetime(object): """Abstract date/time type. Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_datetime.py 1 Mar 2002 21:00:49 -0000 1.1 --- test_datetime.py 1 Mar 2002 22:42:28 -0000 1.2 *************** *** 27,30 **** --- 27,39 ---- self.assert_(dt2 > dt3) + def test_ordinal_conversions(self): + import datetime as _datetime + for year in range(_datetime.MINYEAR, _datetime.MAXYEAR + 1): + for month, day in (1, 1), (12, 31), (6, 17): + base = datetime(year, month, day) + ordinal = _datetime._date2num(base) + derived = _datetime._num2date(ordinal) + self.assertEqual(base, derived) + def test_suite(): s1 = unittest.makeSuite(TestDateTime, 'test')
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4