Skip to content

Commit c943b54

Browse files
authored
Improve clock implementation (#588)
* Prefer python's time.time_ns over libc if available * Improve Windows compatibility of Clock implementation Backport of #589
1 parent 8fb6f33 commit c943b54

File tree

3 files changed

+45
-26
lines changed

3 files changed

+45
-26
lines changed

neo4j/time/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,10 @@ def local_offset(cls):
266266
267267
:raises OverflowError:
268268
"""
269-
return ClockTime(-int(mktime(gmtime(0))))
269+
# Adding and subtracting two days to avoid passing a pre-epoch time to
270+
# `mktime`, which can cause a `OverflowError` on some platforms (e.g.,
271+
# Windows).
272+
return ClockTime(-int(mktime(gmtime(172800))) + 172800)
270273

271274
def local_time(self):
272275
""" Read and return the current local time from this clock, measured relative to the Unix Epoch.

neo4j/time/clock_implementations.py

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,31 @@ def utc_time(self):
4545
return ClockTime(seconds, nanoseconds * 1000)
4646

4747

48+
class PEP564Clock(Clock):
49+
""" Clock implementation based on the PEP564 additions to Python 3.7.
50+
This clock is guaranteed nanosecond precision.
51+
"""
52+
53+
@classmethod
54+
def precision(cls):
55+
return 9
56+
57+
@classmethod
58+
def available(cls):
59+
try:
60+
from time import time_ns
61+
except ImportError:
62+
return False
63+
else:
64+
return True
65+
66+
def utc_time(self):
67+
from time import time_ns
68+
t = time_ns()
69+
seconds, nanoseconds = divmod(t, 1000000000)
70+
return ClockTime(seconds, nanoseconds)
71+
72+
4873
class LibCClock(Clock):
4974
""" Clock implementation that works only on platforms that provide
5075
libc. This clock is guaranteed nanosecond precision.
@@ -79,28 +104,3 @@ def utc_time(self):
79104
return ClockTime(ts.seconds, ts.nanoseconds)
80105
else:
81106
raise RuntimeError("clock_gettime failed with status %d" % status)
82-
83-
84-
class PEP564Clock(Clock):
85-
""" Clock implementation based on the PEP564 additions to Python 3.7.
86-
This clock is guaranteed nanosecond precision.
87-
"""
88-
89-
@classmethod
90-
def precision(cls):
91-
return 9
92-
93-
@classmethod
94-
def available(cls):
95-
try:
96-
from time import time_ns
97-
except ImportError:
98-
return False
99-
else:
100-
return True
101-
102-
def utc_time(self):
103-
from time import time_ns
104-
t = time_ns()
105-
seconds, nanoseconds = divmod(t, 1000000000)
106-
return ClockTime(seconds, nanoseconds)

tests/unit/time/test_clock.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,19 @@ def test_local_offset(self):
5353
clock = object.__new__(Clock)
5454
offset = clock.local_offset()
5555
self.assertIsInstance(offset, ClockTime)
56+
57+
def test_local_time(self):
58+
_ = Clock()
59+
for impl in Clock._Clock__implementations:
60+
self.assert_(issubclass(impl, Clock))
61+
clock = object.__new__(impl)
62+
time = clock.local_time()
63+
self.assertIsInstance(time, ClockTime)
64+
65+
def test_utc_time(self):
66+
_ = Clock()
67+
for impl in Clock._Clock__implementations:
68+
self.assert_(issubclass(impl, Clock))
69+
clock = object.__new__(impl)
70+
time = clock.utc_time()
71+
self.assertIsInstance(time, ClockTime)

0 commit comments

Comments
 (0)