simple SNTP python script
Here is the working script from the Second Edition of Python Network Programming Cookbook:
import socket, struct, sys, time
NTP_SERVER = '0.uk.pool.ntp.org'
TIME1970 = 2208988800
def sntp_client():
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
data = '\x1b' + 47 * '\0'
client.sendto(data.encode('utf-8'), (NTP_SERVER, 123))
data, address = client.recvfrom(1024)
if data: print('Response received from:', address)
t = struct.unpack('!12I', data)[10] - TIME1970
print('\tTime = %s' % time.ctime(t))
if __name__ == '__main__':
sntp_client()
It should be noted that the accepted answer neglects the fraction part of the timestamp, see e.g. IETF RFC5905, p.13. A code snippet including it could look like
import socket
import struct
import datetime
NTP_SERVER = '0.uk.pool.ntp.org'
NTP_DELTA = 2208988800 # given as system epoch (e.g. 1970-1-1) minus NTP epoch (1900-1-1) in [s]
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as client:
data = '\x1b' + 47 * '\0'
client.sendto(data.encode('utf-8'), (NTP_SERVER, 123))
data, _ = client.recvfrom(256)
tx_s, tx_f = struct.unpack('!12I', data)[10:12] # seconds and fractional seconds
tx_timestamp = (tx_s + float(tx_f)/2**32) - NTP_DELTA
print(datetime.datetime.fromtimestamp(tx_timestamp, datetime.timezone.utc))
# e.g.
# 2019-12-18 13:02:14.029521+00:00 # Note: UTC used here for output!
Also keep in mind that this only returns the transmit timestamp (tx; time when the server sent the packet). If you look for the milliseconds, the round trip delay might be signficant (see e.g. p.29 of the linked RFC5905).
Sidenote: the socket docs recommend to open the socket in a with
context so that it is closed properly when not needed anymore.