Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to ntp server time down to millisecond precision using Python ntplib?

Tags:

python

ntp

I am creating a python module that will output the time from a selection of NTP Pool servers to millisecond precision as an exercise in showing how server timestamps vary. Thus far I have been able to print out the origin server timestamp to within a second precision but how can I get the millisecond precision?

ntp_pool = '0.pool.ntp.org', \
       'uk.pool.ntp.org', \
       'ie.pool.ntp.org'

def get_ntp_time():
    for item in ntp_pool:
        call = ntplib.NTPClient()
        response = call.request(item, version=3)
        print(time.ctime(response.orig_time))
like image 949
eoghan.nolan Avatar asked Jul 06 '15 21:07

eoghan.nolan


People also ask

How does NTP synchronize time?

NTP uses Coordinated Universal Time (UTC) to synchronize computer clock times with extreme precision. It offers greater accuracy on smaller networks -- down to 1 millisecond in a local area network (LAN) and within tens of milliseconds over the internet. NTP does not account for time zones.

What is NTPclient?

The Network Time Protocol (NTP) is a client/server application. Each workstation, router, or server must be equipped with NTP client software to synchronize its clock to the network time server. In most cases the client software is already resident in the operating system of each device.

Why to use NTP?

Network Time Protocol (NTP) is a protocol that allows the synchronization of system clocks (from desktops to servers). Having synchronized clocks is not only convenient but required for many distributed applications. Therefore the firewall policy must allow the NTP service if the time comes from an external server.


2 Answers

The for loop is likely to colour your results since there is time passing in each iteration.

In any case, the ntp response is a timestamp with microsecond accuracy, so the limitation seems to be within time.ctime, which only goes down to second-accuracy

You could use datetime.fromtimestamp instead, and optionally also strftime to make it prettier. My example half-heartedly mimics the output of your existing code.

from datetime import datetime

def get_ntp_time():
for item in ntp_pool:
    call = ntplib.NTPClient()
    response = call.request(item, version=3)
    t = datetime.fromtimestamp(response.orig_time)
    print(t.strftime("%a %b %d %H:%M:%S.%f"))
like image 156
chinatsu Avatar answered Nov 01 '22 12:11

chinatsu


I think there's something missleading here: response.orig_time is the time of the client that made the request, not that of the server. See IETF RFC5905, p.23: "Origin Timestamp (org): Time at the client when the request departed for the server [...]". An up-to-date version of the code should look something like

import ntplib
from datetime import datetime, timezone

NTP_SERVERS = ['0.pool.ntp.org', 'uk.pool.ntp.org']

for server in NTP_SERVERS:
    client = ntplib.NTPClient()
    response = client.request(server, version=3)
    print(f"server: {server}")
    print(f"client time of request: {datetime.fromtimestamp(response.orig_time, timezone.utc)}")
    print(f"server responded with: {datetime.fromtimestamp(response.tx_time, timezone.utc)}")

...would give me e.g.

server: 0.pool.ntp.org
client time of request: 2019-12-18 13:58:52.224058+00:00
server responded with: 2019-12-18 13:58:51.289734+00:00
server: uk.pool.ntp.org
client time of request: 2019-12-18 13:58:52.314615+00:00
server responded with: 2019-12-18 13:58:51.377655+00:00

Note that depending on how far the signal has to travel, the round trip delay (response.delay) might be significant if you look for the milliseconds.

like image 1
FObersteiner Avatar answered Nov 01 '22 10:11

FObersteiner