Welcome, guest | Sign In | My Account | Store | Cart

Uses the SNTP protocol (as specified in RFC 2030) to contact the server specified in the command line and report the time as returned by that server. This is about the simplest (and dumbest) client I could manage.

Python, 16 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
from socket import *
import struct
import sys
import time

TIME1970 = 2208988800L      # Thanks to F.Lundh

client = socket( AF_INET, SOCK_DGRAM )
data = '\x1b' + 47 * '\0'
client.sendto( data, ( sys.argv[1], 123 ))
data, address = client.recvfrom( 1024 )
if data:
    print 'Response received from:', address
    t = struct.unpack( '!12I', data )[10]
    t -= TIME1970
    print '\tTime=%s' % time.ctime(t)

I would like too see a more complete implementation of SNTP or even full-blown NTP in Python. Anyone interested? I might even try it myself.

4 comments

Jeff Bauer 18 years, 10 months ago  # | flag

from socket import *. Nice job in a few lines of code. I'd like to see the namespace-polluting import line replaced, especially in published Python code.

replace: from socket import *
with:    from socket import socket, AF_INET, SOCK_DGRAM
Simon Foster 18 years, 8 months ago  # | flag

Done as requested. I can't login to change this code having lost my account details but the codes so short I can just post it here.

import socket
import struct
import sys
import time

TIME1970 = 2208988800L      # Thanks to F.Lundh

client = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
data = '\x1b' + 47 * '\0'
client.sendto( data, ( sys.argv[1], 123 ))
data, address = client.recvfrom( 1024 )
if data:
    print 'Response received from:', address
    t = struct.unpack( '!12I', data )[10]
    t -= TIME1970
    print '\tTime=%s' % time.ctime(t)
Thomas Guettler 11 years, 10 months ago  # | flag

Thank you Simon Foster, this recipe helped me a lot. Up to now I used sntp with subprocess, but this brings me this error very often:

sntp: unable to format current local time

Craig Ransom 6 years, 10 months ago  # | flag

I'm having a spot of bother with this script, in Python 3.4.2.

The line in question including the error message looks like:

>>> client = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
>>> data = '\x1b' + 47 * '\0'
>>> client.sendto( data, ('time.nist.gov', 123) )
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' does not support the buffer interface

I'm not sure how to correctly format the sendto line, and the data line looks suspicious also.