classification
Title: datetime.fromtimestamp fails with negative fractional times
Type: Stage:
Components: Library (Lib) Versions: Python 2.5
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: georg.brandl, gvanrossum, jamesh, ocean-city
Priority: normal Keywords:

Created on 2007-01-29 02:21 by jamesh, last changed 2007-03-07 16:13 by georg.brandl. This issue is now closed.

Files
File name Uploaded Description Edit
datetime.patch gvanrossum, 2007-03-05 18:38 patch + unittest
Messages (13)
msg31113 - (view) Author: James Henstridge (jamesh) Date: 2007-01-29 02:21
The datetime.fromtimestamp() function works fine with integer timestamps and positive fractional timestamps, but fails if I pass a negative fractional timestamp.  For example:

>>> import datetime
>>> datetime.datetime.fromtimestamp(-1.05)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: microsecond must be in 0..999999

It should return the same result as datetime.fromtimestamp(-1) - timedelta(seconds=.5).

The same bug can be triggered in datetime.utcfromtimestamp().

I have been able to reproduce this bug in Python 2.4.4 and Python 2.5 on Linux.
msg31114 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2007-03-02 16:05
Looks like a bug in the conversion from floats to ints.  Anyone care to track it down more precisely?
msg31115 - (view) Author: James Henstridge (jamesh) Date: 2007-03-05 10:23
The problem seems to be in datetime_from_timestamp() from datetimemodule.c.  It should probably be checking to see whether the microseconds value it calculates is negative, and adjust "timet" and "us" accordingly if so.
msg31116 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2007-03-05 18:38
Attached is a fix. If this is to your liking I'll check it in.
File Added: datetime.patch
msg31117 - (view) Author: James Henstridge (jamesh) Date: 2007-03-06 00:03
I just tried the patch, and can confirm that it fixes the problem with datetime.fromtimestamp() and datetime.utcfromtimestamp().  The logic in the patch looks correct.
msg31118 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2007-03-06 15:50
Committed revision 54167.

I'm leaving this open until it's been backported to the 2.5 branch.
msg31119 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2007-03-06 17:59
Georgbot backported this to 2.5.
msg31120 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2007-03-06 18:15
Though, the new tests seem to fail on Windows (I noticed that only after backporting, since most other buildbot failures were due to the cmp/key problem in setup.py).
msg31121 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2007-03-06 18:34
That's too bad. More details?
msg31122 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2007-03-06 18:45
Not from me, no Windows around.
msg31123 - (view) Author: Hirokazu Yamamoto (ocean-city) * (Python committer) Date: 2007-03-07 07:34
Hello, I'm user of Windows (Now building Python2.5 with VC6)
I heard localtime() can only handle positive time_t on windows,
so datetime.fromtimestamp() also fails for negative value.

>>> datetime.datetime.fromtimestamp(-1.05)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: timestamp out of range for platform localtime()/gmtime() function
>>> datetime.datetime.fromtimestamp(-1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: timestamp out of range for platform localtime()/gmtime() function

I'll attach workaround for unittest. Probably there is better way
skip this test on non-negative platform though :-)

Index: Lib/test/test_datetime.py
===================================================================
--- Lib/test/test_datetime.py	(revision 54194)
+++ Lib/test/test_datetime.py	(working copy)
@@ -1428,9 +1428,17 @@
     def test_negative_float_fromtimestamp(self):
         # The result is tz-dependent; at least test that this doesn't
         # fail (like it did before bug 1646728 was fixed).
+        try:
+            self.theclass.fromtimestamp(-1)
+        except ValueError: # cannot handle negative value
+            return
         self.theclass.fromtimestamp(-1.05)
 
     def test_negative_float_utcfromtimestamp(self):
+        try:
+            self.theclass.utcfromtimestamp(-1)
+        except ValueError: # cannot handle negative value
+            return
         d = self.theclass.utcfromtimestamp(-1.05)
         self.assertEquals(d, self.theclass(1969, 12, 31, 23, 59, 58, 950000))
msg31124 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2007-03-07 15:17
Thanks!  I'm skipping these tests on Windows now.
Committed revision 54209.

Georgbot, would you be so kind... :-)
msg31125 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2007-03-07 16:13
Certainly. Backported in rev. 54211.
History
Date User Action Args
2007-01-29 02:21:31jameshcreate