pythontimentp

Convert NTP timestamp to Unix time


I am getting the current time from an NTP server. The reference epoch of NTP is 0:00:00.000 on 1 January 1900 and the library I use for NTP returns the number of seconds that elapsed since that reference epoch. As you can see, it works similarily to Unix time, except that it uses a different reference epoch. My goal is therefore to convert this NTP timestamp to a unix timestamp, while avoiding all those weird things like leap years, leap seconds and all those other weird things that humans did to their time scale.

The naive approach would obviously be to calculate the number of seconds that happened between the NTP reference epoch and the Unix reference epoch, store that as a constant and subtract that from the NTP timestamp, but I have a feeling that I would be too stupid for that and forget some of the aforementioned oddities. My question is therefore whether Python has some built-in function or whether there's a library to do just that.


Solution

  • The ntplib python library converts the NTP timestamp to/from Unix time as seconds since 1-Jan-1970.

    import ntplib
    from datetime import datetime, timezone
    
    dt = datetime.now(timezone.utc)
    ts = dt.timestamp()
    print("datetime:", dt)
    print("timestamp:", ts)
    
    # convert native timestamp to NTP time
    ntptime = ntplib.system_to_ntp_time(ts)
    print("NTP time: ", ntptime)
    
    # convert NTP time to native timestamp
    ts = ntplib.ntp_to_system_time(ntptime)
    print("timestamp:", ts)
    

    Output:

    datetime: 2022-02-01 18:22:56.530085+00:00
    timestamp: 1643739776.530085
    NTP time:  3852728576.530085
    

    The library also implements a NTP client to query a NTP server and return the associated time from the request and its response.

    import ntplib
    from datetime import datetime
    
    client = ntplib.NTPClient()
    server = 'pool.ntp.org'
    
    resp = client.request(server, version=3)
    
    print("offset", resp.offset)
    print("delay", resp.delay)
    
    # timestamps are converted to native "UNIX" timestamps
    print(resp.orig_time)
    
    print("orig_time:", datetime.utcfromtimestamp(resp.orig_time))
    print("recv_time:", datetime.utcfromtimestamp(resp.recv_time))
    print("tx_time  :", datetime.utcfromtimestamp(resp.tx_time))
    print("dest_time:", datetime.utcfromtimestamp(resp.dest_time))
    

    Output:

    offset 0.007886648178100586
    delay 0.002925395965576172
    1643738937.685132
    orig_time: 2022-02-01 18:08:57.685132
    recv_time: 2022-02-01 18:08:57.693858
    tx_time  : 2022-02-01 18:08:57.693956
    dest_time: 2022-02-01 18:08:57.688134