27
27
28
28
NTP_TO_UNIX_EPOCH = 2208988800 # 1970-01-01 00:00:00
29
29
30
+
30
31
class NTP :
31
32
"""Network Time Protocol (NTP) helper module for CircuitPython.
32
33
This module does not handle daylight savings or local time. It simply requests
33
34
UTC from a NTP server.
34
35
"""
35
36
36
- def __init__ (self , socketpool , * , server : str = "0.adafruit.pool.ntp.org" , port : int = 123 , tz_offset : int = 0 ) -> None :
37
+ def __init__ (
38
+ self ,
39
+ socketpool ,
40
+ * ,
41
+ server : str = "0.adafruit.pool.ntp.org" ,
42
+ port : int = 123 ,
43
+ tz_offset : int = 0 ,
44
+ ) -> None :
37
45
"""
38
46
:param object socketpool: A socket provider such as CPython's `socket` module.
39
47
:param str server: The domain of the ntp server to query.
40
48
:param int port: The port of the ntp server to query.
41
49
:param float tz_offset: Timezone offset in hours from UTC. Only useful for timezone ignorant
42
- CircuitPython. CPython will determine timezone automatically and adjust (so don't use this.)
43
- For example, Pacific daylight savings time is -7.
50
+ CircuitPython. CPython will determine timezone automatically and adjust (so don't use
51
+ this.) For example, Pacific daylight savings time is -7.
44
52
"""
45
53
self ._pool = socketpool
46
54
self ._server = server
@@ -56,19 +64,29 @@ def __init__(self, socketpool, *, server: str="0.adafruit.pool.ntp.org", port: i
56
64
57
65
@property
58
66
def datetime (self ) -> time .struct_time :
67
+ """Current time from NTP server."""
59
68
if time .monotonic_ns () > self .next_sync :
60
69
self ._packet [0 ] = 0b00100011 # Not leap second, NTP version 4, Client mode
61
70
for i in range (1 , len (self ._packet )):
62
71
self ._packet [i ] = 0
63
72
with self ._pool .socket (self ._pool .AF_INET , self ._pool .SOCK_DGRAM ) as sock :
64
73
sock .sendto (self ._packet , (self ._server , self ._port ))
65
- size , address = sock .recvfrom_into (self ._packet )
74
+ sock .recvfrom_into (self ._packet )
66
75
# Get the time in the context to minimize the difference between it and receiving
67
76
# the packet.
68
77
destination = time .monotonic_ns ()
69
78
poll = struct .unpack_from ("!B" , self ._packet , offset = 2 )[0 ]
70
- self .next_sync = destination + (2 ** poll ) * 1_000_000_000
71
- seconds = struct .unpack_from ("!I" , self ._packet , offset = len (self ._packet ) - 8 )[0 ]
72
- self ._monotonic_start = seconds + self ._tz_offset - NTP_TO_UNIX_EPOCH - (destination // 1_000_000_000 )
79
+ self .next_sync = destination + (2 ** poll ) * 1_000_000_000
80
+ seconds = struct .unpack_from (
81
+ "!I" , self ._packet , offset = len (self ._packet ) - 8
82
+ )[0 ]
83
+ self ._monotonic_start = (
84
+ seconds
85
+ + self ._tz_offset
86
+ - NTP_TO_UNIX_EPOCH
87
+ - (destination // 1_000_000_000 )
88
+ )
73
89
74
- return time .localtime (time .monotonic_ns () // 1_000_000_000 + self ._monotonic_start )
90
+ return time .localtime (
91
+ time .monotonic_ns () // 1_000_000_000 + self ._monotonic_start
92
+ )
0 commit comments