pokerbirch
October 13th, 2011, 07:59 PM
I have a project which connects to a server via an official API, however they provide no means of time synchronisation and rely on the user having an NTP sync'd pc clock. I don't want to force the the users of my script to keep their systems updated via NTP, so instead I want to calculate the offset within my script. All time objects of the API default to UTC/GMT.
Here's my code so far:
import struct
from time import time
from socket import socket, AF_INET, SOCK_DGRAM
from datetime import datetime
def send_ntp_request(self):
"""gets NTP time and returns a datetime object"""
try:
sock = socket(AF_INET, SOCK_DGRAM)
sock.settimeout(5)
data = '\x1b' + 47 * '\0'
start_time = time()
sock.sendto(data, ('uk.pool.ntp.org', 123))
data, ip = sock.recvfrom(1024)
req_time = time() - start_time
if data:
timestamp = struct.unpack('!12I', data)[10]
timestamp -= 2208988800L # = date in sec since epoch
timestamp += req_time / 2
return datetime.utcfromtimestamp(timestamp)
except:
return 'ERROR: socket request failed'
Does this appear to be correct? It seems OK but I'm a little unsure of my handling of the actual request time. Is timestamp += req_time / 2 sufficient? I don't need micro second accuracy but would like to be within 0.5 seconds.
Here's my code so far:
import struct
from time import time
from socket import socket, AF_INET, SOCK_DGRAM
from datetime import datetime
def send_ntp_request(self):
"""gets NTP time and returns a datetime object"""
try:
sock = socket(AF_INET, SOCK_DGRAM)
sock.settimeout(5)
data = '\x1b' + 47 * '\0'
start_time = time()
sock.sendto(data, ('uk.pool.ntp.org', 123))
data, ip = sock.recvfrom(1024)
req_time = time() - start_time
if data:
timestamp = struct.unpack('!12I', data)[10]
timestamp -= 2208988800L # = date in sec since epoch
timestamp += req_time / 2
return datetime.utcfromtimestamp(timestamp)
except:
return 'ERROR: socket request failed'
Does this appear to be correct? It seems OK but I'm a little unsure of my handling of the actual request time. Is timestamp += req_time / 2 sufficient? I don't need micro second accuracy but would like to be within 0.5 seconds.