@@ -46,6 +46,7 @@ def __init__(
46
46
port : int = 123 ,
47
47
tz_offset : float = 0 ,
48
48
socket_timeout : int = 10 ,
49
+ cache_seconds : int = 0 ,
49
50
) -> None :
50
51
"""
51
52
:param object socketpool: A socket provider such as CPython's `socket` module.
@@ -55,6 +56,8 @@ def __init__(
55
56
CircuitPython. CPython will determine timezone automatically and adjust (so don't use
56
57
this.) For example, Pacific daylight savings time is -7.
57
58
:param int socket_timeout: UDP socket timeout, in seconds.
59
+ :param int cache_seconds: how many seconds to use a cached result from NTP server
60
+ (default 0, which respects NTP server's minimum).
58
61
"""
59
62
self ._pool = socketpool
60
63
self ._server = server
@@ -63,6 +66,7 @@ def __init__(
63
66
self ._packet = bytearray (PACKET_SIZE )
64
67
self ._tz_offset = int (tz_offset * 60 * 60 )
65
68
self ._socket_timeout = socket_timeout
69
+ self ._cache_seconds = cache_seconds
66
70
67
71
# This is our estimated start time for the monotonic clock. We adjust it based on the ntp
68
72
# responses.
@@ -74,7 +78,8 @@ def __init__(
74
78
def datetime (self ) -> time .struct_time :
75
79
"""Current time from NTP server. Accessing this property causes the NTP time request,
76
80
unless there has already been a recent request. Raises OSError exception if no response
77
- is received within socket_timeout seconds"""
81
+ is received within socket_timeout seconds, ArithmeticError for substantially incorrect
82
+ NTP results."""
78
83
if time .monotonic_ns () > self .next_sync :
79
84
if self ._socket_address is None :
80
85
self ._socket_address = self ._pool .getaddrinfo (self ._server , self ._port )[
@@ -92,8 +97,11 @@ def datetime(self) -> time.struct_time:
92
97
# the packet.
93
98
destination = time .monotonic_ns ()
94
99
poll = struct .unpack_from ("!B" , self ._packet , offset = 2 )[0 ]
95
- self .next_sync = destination + (2 ** poll ) * 1_000_000_000
100
+
101
+ cache_offset = max (2 ** poll , self ._cache_seconds )
102
+ self .next_sync = destination + cache_offset * 1_000_000_000
96
103
seconds = struct .unpack_from ("!I" , self ._packet , offset = PACKET_SIZE - 8 )[0 ]
104
+
97
105
self ._monotonic_start = (
98
106
seconds
99
107
+ self ._tz_offset
0 commit comments