-
-
Notifications
You must be signed in to change notification settings - Fork 30.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
datetime operations spanning MINYEAR give bad results #51399
Comments
The datetime module documentation would imply that operations that cause Python 2.6.3 (r263rc1:75186, Oct 2 2009, 20:40:30) [MSC v.1500 32 bit
(Intel)]
on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import datetime
>>> t0=datetime.datetime(1,1,1)
>>> d1, d2, d3 = map(datetime.timedelta, range(1,4))
# The following is expected and accoring to the docs:
>>> t0-d1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: date value out of range
# The following is completely bogus:
>>> t0-d2
datetime.datetime(1, 0, 255, 0, 0)
# The two following behaving differently may be very confusing,
# the second one is correct
>>> t0-d2+d3
datetime.datetime(1, 8, 15, 0, 0)
>>> t0+d3-d2
datetime.datetime(1, 1, 2, 0, 0)
>>> |
The issue is present in Python 3.0 and 2.5 as well. Python 2.5.1 (r251:54863, Jul 17 2008, 13:21:31)
[GCC 4.3.1 20080708 (Red Hat 4.3.1-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import datetime
>>> t0=datetime.datetime(1,1,1)
>>> d1,d2,d3=map(datetime.timedelta, range(1,4))
>>> t0-d1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: date value out of range
>>> t0-d2
datetime.datetime(1, 0, 255, 0, 0) I think this is bug in datetime for all Python versions |
The problem seems to be in the "normalize_date" function in I have a patch which fixes this problem. It checks for month range anand@anand-laptop:~/projects/python/py3k$ ./python
Python 3.2a0 (py3k:75627, Oct 25 2009, 14:28:21)
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
Traceback (most recent call last):
File "/home/anand/.pythonrc", line 2, in <module>
import readline
ImportError: No module named readline
>>> import datetime
>>> t0=datetime.datetime(1,1,1)
>>> d1,d2,d3=map(datetime.timedelta, range(1,4))
>>> t0-d1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: date value out of range
>>> t0-d2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: date value out of range
>>> t0-d3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: date value out of range
>>> d0=datetime.timedelta(0)
>>> t0-d0
datetime.datetime(1, 1, 1, 0, 0)
>>> Svn diff is attached. |
The patch seems OK, but needs tests. |
Given
at the end of normalize_y_m_d(), it looks like at lest 1 <=*month and 1 <=*day are redundant. A closer look also reveals
in the middle of normalize_y_m_d(). This seems to leave only *day <=31 possibly relevant. I suspect that out of bounds day surviving normalize_y_m_d() is a logical error in that function that needs to be fixed and an assert() added at the end. The proposed patch appears to cure the symptom rather than the actual flaw. |
Aha! My reliance on asserts() was misguided. With the debug build: >>> t0-d2
Assertion failed: (ordinal >= 1), function ord_to_ymd, file /Users/sasha/Work/python-svn/trunk/Modules/datetimemodule.c, line 269.
Abort trap Should we reclassify this bug as a crash? |
No, because normally distributions do not use debug builds. |
I am attaching my variant of the patch including additional unit tests. Note that my changes make normalize_y_m_d() and normalize_date() the same, but I am leaving the current structure intact to make reviewer's job easier. |
Can someone update this issue ? Is the 2nd patch tested... ? |
My patch includes unit tests and I tested it on Mac OS X. Anand, what kind of testing do you have in mind? |
I've untabified my last patch and added a NEWS entry. I believe it is ready for commit review. Mark? |
I'll take a look at this patch later today. |
The patch looks good to me. Please apply! |
As an aside, I dislike the fact that the datetime module uses a C 'int' for date ordinals, and clearly assumes that it'll be at least 32 bits. int could be as small as 16 bits on some systems (small embedded systems?). But that's another issue. |
Committed in r81566 (trunk), r81568 (py3k), r81569 (release26-maint), r81570 (release31-maint). |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: