[Python-checkins] CVS: python/nondist/sandbox/datetime datetime.py,1.28,1.29

Tim Peters tim_one@users.sourceforge.net
2002年3月03日 16:14:56 -0800


Update of /cvsroot/python/python/nondist/sandbox/datetime
In directory usw-pr-cvs1:/tmp/cvs-serv10857
Modified Files:
	datetime.py 
Log Message:
_ord2ymd(): Deal with the switch to year-one based computation more
gracefully, and add extensive explanation.
Index: datetime.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v
retrieving revision 1.28
retrieving revision 1.29
diff -C2 -d -r1.28 -r1.29
*** datetime.py	3 Mar 2002 23:16:21 -0000	1.28
--- datetime.py	4 Mar 2002 00:14:54 -0000	1.29
***************
*** 71,94 ****
 "ordinal -> (year, month, day), considering 01-Jan-0001 as day 1."
 
! n400 = (n-1) // _DI400Y # number of 400-year blocks preceding
! year = n400 * 400 + 1
! n -= n400 * _DI400Y
 
! more = n // 365
! dby = _days_before_year(more + 1)
! if dby >= n:
! dby -= _days_in_year(more)
! more -= 1
! year += more
! assert n > dby
! 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)
! assert n > dbm
! return year, month, n-dbm
 
 # Month and day names. For localized versions, see the calendar module.
--- 71,126 ----
 "ordinal -> (year, month, day), considering 01-Jan-0001 as day 1."
 
! # n is a 1-based index, starting at 1-Jan-1. The pattern of leap years
! # repeats exactly every 400 years. The basic strategy is to find the
! # closest 400-year boundary at or before n, then work with the offset
! # from that boundary to n. Life is much clearer if we subtract 1 from
! # n first -- then the values of n at 400-year boundaries are exactly
! # those divisible by _DI400Y:
! #
! # D M Y n n-1
! # -- --- ---- ---------- ----------------
! # 31 Dec -400 -_DI400Y -_DI400Y -1
! # 1 Jan -399 -_DI400Y +1 -_DI400Y 400-year boundary
! # ...
! # 30 Dec 000 -1 -2
! # 31 Dec 000 0 -1
! # 1 Jan 001 1 0 400-year boundary
! # 2 Jan 001 2 1
! # 3 Jan 001 3 2
! # ...
! # 31 Dec 400 _DI400Y _DI400Y -1
! # 1 Jan 401 _DI400Y +1 _DI400Y 400-year boundary
! n -= 1
! n400, n = divmod(n, _DI400Y)
! year = n400 * 400 + 1 # ..., -399, 1, 401, ...
 
! # Now n is the (non-negative) offset, in days, from January 1 of year, to
! # the desired date. First compute how many whole years precede the
! # desired date. Dividing by 365 gives an upper bound quickly, and it's
! # easy to show that it's either exact or one too large (note that this
! # relies on that n < _DI400Y; if we did this before factoring out a close
! # 400-year boundary, there's no bound on how far off n//365 could be).
! whole_years_preceding = n // 365
! exact_days = _days_before_year(whole_years_preceding + 1)
! if exact_days > n: # estimate is too large
! exact_days -= _days_in_year(whole_years_preceding)
! whole_years_preceding -= 1
! assert 0 <= exact_days <= n
! year += whole_years_preceding
! n -= exact_days
 
+ # Now the year is correct, and n is the offset from January 1. We find
+ # the month via another estimate that's either exact or one too large.
 month = min(n//29 + 1, 12)
! exact_days = _days_before_month(month, year)
! if exact_days > n: # estimate is too large
 month -= 1
! exact_days -= _days_in_month(month, year)
! assert 0 <= exact_days <= n
! n -= exact_days
! 
! # Now the year and month are correct, and n is the offset from the
! # start of that month: we're done!
! return year, month, n+1
 
 # Month and day names. For localized versions, see the calendar module.

AltStyle によって変換されたページ (->オリジナル) /