-
-
Notifications
You must be signed in to change notification settings - Fork 31.5k
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
gh-81708: Fixing the "Invalid argument" bug on datetime.timestamp()
#15498
base: main
Are you sure you want to change the base?
Conversation
Hello, and thanks for your contribution! I'm a bot set up to make sure that the project can legally accept your contribution by verifying you have signed the PSF contributor agreement (CLA). Unfortunately we couldn't find an account corresponding to your GitHub username on bugs.python.org (b.p.o) to verify you have signed the CLA (this might be simply due to a missing "GitHub Name" entry in your b.p.o account settings). This is necessary for legal reasons before we can look at your contribution. Please follow the steps outlined in the CPython devguide to rectify this issue. You can check yourself to see if the CLA has been received. Thanks again for your contribution, we look forward to reviewing it! |
Thank you for your PR, would you mind following the guide here and attaching the bugs.python.org issue in the commit and PR messages: https://bugs.python.org/issue37527 Aside from that, here's some things you might wanna fix in the code. Add a regression test for this particular case on windows. Fix the existing failing tests. Note that the datetime module has a C implementation here that should be kept in sync with the Python version: cpython/Modules/_datetimemodule.c Line 6044 in c5b242f
|
I konw a little about C. Fixing the datetime.c is too challenging for me. |
@pingchaoc, are you interested in continuing to work on this PR? |
Any updates on this issue? I have encountered the bug today and would be very happy to get a new pach. |
@seljasen Since this has been stale so long, I think you're safe to work an alternate patch for this. If you use @pingchaoc's original work, please add in a:
into the CL description. |
I have the same problem still on python 3.8.7 on windows. This is now almost 2 years later and datetime is a fundamental system function. Can I request higher priority for this? how to reproduce:
|
datetime.timestamp()
Most changes to Python require a NEWS entry. Please add it using the blurb_it web app or the blurb command-line tool. |
Probably also fixes gh-94414. |
This PR breaks The only thing that I could do is to move an attached test into a proper location: diff --git a/test.py b/test.py
deleted file mode 100644
index 0562011196..0000000000
--- a/test.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# datetime.timestamp() fails when the 'datetime' is close to the Epoch
-# Here is the test runs on win10 os, python3.7-3.9. My time is 'utc +8'
-
-from datetime import datetime
-
-def test(year,month,day,hour=0,minute=0,second=0):
- t = datetime(year,month,day,hour)
- try:
- print(t.timestamp())
- except Exception as e:
- print(e)
- return
-
-test(1970,1,1)
-test(1970,1,1,8)
:
--- a/Lib/test/datetimetester.py
+++ b/Lib/test/datetimetester.py
@@ -6629,6 +6629,26 @@ def test_datetime_from_timestamp(self):
self.assertEqual(dt_orig, dt_rt)
+class EdgeCaseTests(unittest.TestCase):
+
+ def test_near_the_epoch(self):
+ # gh-81708: datetime.timestamp() may fail when the 'datetime'
+ # is close to the Epoch.
+ precisions = (
+ (1970, 1, 1, 0, 0, 0),
+ (1970, 1, 1, 8, 0, 0),
+ (1970, 1, 2, 7, 59, 59),
+ (1970, 1, 2, 8, 0, 0) # this time is just okay
+ )
+ for date_tuple in precisions:
+ year, month, day, hour, minute, second = date_tuple
+ with self.subTest(date=date_tuple):
+ instance = datetime(year, month, day, hour)
+ self.assertIsNotNone(instance)
+ timestamp = instance.timestamp()
+ self.assertIsNotNone(timestamp)
+
+
def load_tests(loader, standard_tests, pattern):
standard_tests.addTest(ZoneInfoCompleteTest())
return standard_tests
diff --git a/test.py b/test.py
deleted file mode 100644
index 0562011196..0000000000
--- a/test.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# datetime.timestamp() fails when the 'datetime' is close to the Epoch
-# Here is the test runs on win10 os, python3.7-3.9. My time is 'utc +8'
-
-from datetime import datetime
-
-def test(year,month,day,hour=0,minute=0,second=0):
- t = datetime(year,month,day,hour)
- try:
- print(t.timestamp())
- except Exception as e:
- print(e)
- return
-
-test(1970,1,1)
-test(1970,1,1,8)
-test(1970,1,2,7,59,59)
-test(1970,1,2,8) # this time is just okay |
Fixing the "Invalid argument" bug on datetime.timestamp()
I found a bug in the Python built-in library datetime. In the Windows os, from Python 3.6 to the latest version, datetime.timestamp() will report an "Invalid argument" error, even though it shouldn't.
For instance, when I try to get the timestamp of datetime(1970,1,2,6), the "Invalid argument" error occurs.
I checked the file "datetime.py", the timestamp() uses _mktime(u1) to return a timestmap and the _mktime(u1) employs the local(u1) to get the struct time. When u1 is negetive, the local(u1) throws the "Invalid argument" exception. Here are some codes in the datetime.py ,"u2 = u1 + (-max_fold_seconds, max_fold_seconds)[self.fold]; b = local(u2) - u2 ", self.fold is zero as default.
The u2 becomes the smallest argument for local(u), u2 is used for check if the time fold(Summer time or Winter time) exists. It seems there is no problems about Summer/Winter time around the Epoch (1970,1,1).
I added the simple judgement, which could make sure the "Invalid argument" do not happen when the datetime is near the Epoch.
https://bugs.python.org/issue37527