summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorAmmar Askar <ammar_askar@hotmail.com>2018-07-25 16:54:58 (GMT)
committerAlexander Belopolsky <abalkin@users.noreply.github.com>2018-07-25 16:54:58 (GMT)
commit96d1e69a12ed8ab80203277e1abdaf573457a964 (patch)
treee6cdbe9b8eec222ba25cf313c0ba4361f2dd68d9 /Lib
parent74102c9a5f2327c4fc47feefa072854a53551d1f (diff)
downloadcpython-96d1e69a12ed8ab80203277e1abdaf573457a964.zip
cpython-96d1e69a12ed8ab80203277e1abdaf573457a964.tar.gz
cpython-96d1e69a12ed8ab80203277e1abdaf573457a964.tar.bz2
bpo-29097: Forego fold detection on windows for low timestamp values (GH-2385)
On Windows, passing a negative value to local results in an OSError because localtime_s on Windows does not support negative timestamps. Unfortunately this means that fold detection for timestamps between 0 and max_fold_seconds will result in this OSError since we subtract max_fold_seconds from the timestamp to detect a fold. However, since we know there haven't been any folds in the interval [0, max_fold_seconds) in any timezone, we can hackily just forego fold detection for this time range on Windows.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/datetime.py9
-rw-r--r--Lib/test/datetimetester.py7
2 files changed, 15 insertions, 1 deletions
diff --git a/Lib/datetime.py b/Lib/datetime.py
index 5e922c8..cff9203 100644
--- a/Lib/datetime.py
+++ b/Lib/datetime.py
@@ -6,6 +6,7 @@ time zone and DST data sources.
import time as _time
import math as _math
+import sys
def _cmp(x, y):
return 0 if x == y else 1 if x > y else -1
@@ -1572,6 +1573,14 @@ class datetime(date):
# 23 hours at 1969-09-30 13:00:00 in Kwajalein.
# Let's probe 24 hours in the past to detect a transition:
max_fold_seconds = 24 * 3600
+
+ # On Windows localtime_s throws an OSError for negative values,
+ # thus we can't perform fold detection for values of time less
+ # than the max time fold. See comments in _datetimemodule's
+ # version of this method for more details.
+ if t < max_fold_seconds and sys.platform.startswith("win"):
+ return result
+
y, m, d, hh, mm, ss = converter(t - max_fold_seconds)[:6]
probe1 = cls(y, m, d, hh, mm, ss, us, tz)
trans = result - probe1 - timedelta(0, max_fold_seconds)
diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py
index 7d4cdac..f647a23 100644
--- a/Lib/test/datetimetester.py
+++ b/Lib/test/datetimetester.py
@@ -70,7 +70,7 @@ class TestModule(unittest.TestCase):
if not name.startswith('__') and not name.endswith('__'))
allowed = set(['MAXYEAR', 'MINYEAR', 'date', 'datetime',
'datetime_CAPI', 'time', 'timedelta', 'timezone',
- 'tzinfo'])
+ 'tzinfo', 'sys'])
self.assertEqual(names - allowed, set([]))
def test_divide_and_round(self):
@@ -4955,6 +4955,11 @@ class TestLocalTimeDisambiguation(unittest.TestCase):
self.assertEqual(t0.fold, 0)
self.assertEqual(t1.fold, 1)
+ def test_fromtimestamp_low_fold_detection(self):
+ # Ensure that fold detection doesn't cause an
+ # OSError for really low values, see bpo-29097
+ self.assertEqual(datetime.fromtimestamp(0).fold, 0)
+
@support.run_with_tz('EST+05EDT,M3.2.0,M11.1.0')
def test_timestamp(self):
dt0 = datetime(2014, 11, 2, 1, 30)