httptime#

httptime is a small utility to detect and correct time skew of the system clock.

Introduction#

This utility can update your system time based on the Date header of an HTTP response. This is useful in cases where you need to update your time without an NTP daemon.

It sounds like using the Date header can only get you a second-level granularity, but with some clever logic you can achieve much better accuracy.

Like this project? Don’t forget to give it a star!

Download#

The program, including all of this documentation, is a self-contained Python script without any dependencies. This makes it easy to deploy and use.

You can wget a copy of the script here.

How to install?#

$ wget https://raw.githubusercontent.com/gkbrk/scripts/master/httptime
$ chmod +x httptime
$ sudo cp httptime /usr/bin/httptime

Usage#

After you download and/or install it, you can run httptime and it will report your clock skew. It does not change your system time, it only prints the offset from the real time.

$ httptime
Your time is 2.7 seconds behind.

If you also pass the –set flag, your system time will be adjusted after determining the skew.

$ httptime
Your time is 2.7 seconds behind.
$ sudo httptime --set
$ httptime
Your time is 0.001 seconds behind.

You need to have root permissions, or give the appropriate permissions to the httptime binary in order to modify your system time.

If you want to keep your system time synced, you can add it to your crontab.

*/15 * * * * /home/leo/scripts/httptime --set

Autogenerated docs#

I tried to document the useful stuff above. There is also the auto-generated documentation that’s generated from the code. In case there is anything useful to you here.

httptime.addr = ('1.1.1.1', 80)#

The address of the HTTP server to connect to.

This can be any HTTP server as long as the server time is reasonably accurate.

httptime.frac(n)#

Return the fractional part of a time value.

Parameters
nint

The time value

Returns
int

Fractional part of the time value

httptime.get_skew(f, N)#

Determine the time skew by making N requests to the server.

Usually 4 iterations is enough for an accurate sync and anything above 8 doesn’t provide extra accuracy.

Parameters
ffile

The file object that is bound to the socket.

Nint

The number of requests to make.

Returns
float

The time skew in seconds.

Notes

The Date header has a one second granularity, but it is possible to get more sub-second accuracy by making multiple requests and timing them correctly.

The data has one-second resolution, but we can get more accuracy out of it if we can determine at which point it is 10:15:12.000 instead of just 10:15:12.

The function maintains two values through the iterations, the lower bound of the time skew and the upper bound of the time skew.

At the end of each iteration, we determine how much time we need to sleep in order to align ourselves better with the passing of each second on the server. The better aligned we are, the smaller the spread between the upper and lower bounds.

Once the spread is small enough, or we do a certain number of iterations, we can get the mean value of the upper and lower bounds, and use that as the skew.

httptime.get_time(f)#

Get the current datetime from the server

This function makes an HTTP request to the server, parses the date header and returns it as a timestamp.

Parameters
ffile

The file object that is bound to the socket

Returns
transmitfloat

The timestamp of when the request was sent.

receivefloat

The timestamp of when the response was received.

datetimefloat

The date header returned by the server parsed into a unix timestamp

httptime.parse_http_date(date)#

Parse an HTTP date into a Unix timestamp.

Parameters
datestr

The date to parse (from the HTTP header)

Returns
float

Unix timestamp of the parsed date

httptime.send_request(f)#

Send a HEAD request to the server.

This function sends a HEAD request to the server. It uses TCP sockets instead of an HTTP library in order to minimize the number of unnecessary data.

This helps reduce the data transfer and makes the timing more accurate.

Parameters
ffile

The file object that is bound to the socket.

Returns
None
httptime.set_time(skew)#

Corrects the time skew by using the settime call.

Parameters
skewfloat

The time skew in seconds

Returns
None
Raises
PermissionError

If the current user does not have permission to change the system clock.

See also

time.clock_settime

Sets the system time