in

# Time on Unix, Hacker News

Sections

#### (What is time    Representing time    (Where do we usually find time on Unix    System time, hardware time, internal timers    Syncing time with external sources [NIST]    What depends on time    Human perception of time ` What is time ` (Time is relative    Measuring time and standards

Coordinating time

Time Zones

## We’ve decided to split it as seasons pass, counting one full cycle of the 4 seasons as a year, a full rotation around the sun. We’ve also divided the passing of light to the lack thereof as days, a rotation of the earth on itself. Moving on to more precise clock divisions such as seconds, minutes, and hours, units that meant different things at different points in history. Ultimately, as travel got faster, the different ways of counting time that evolved in multiple places had to converge. People had to agree on what it all meant.

In physics, time is the progression of events, without events there’s no time. It is defined by its measurement, what changes at a specific interval can be considered a unit, though still infinitely divisible.

In physics there are two ways to view time. In classical physics, time is absolute, independent of the perceiver, synchronized for everyone. While in modern physics, we have Einstein’s special and general relativity that applies, things depend on a frame of reference, time can dilate or contract with the effect of gravity, we talk of space-time. In physics, equations work equally well in both ways, the math holds up, in the future and in the past. However, the arrow of time in our universe seems to go in a unique direction. Peculiarly, we’ll see that time in computers, unlike in our universe, can actually go backward at specific events.

All of this to say that because of the importance of tracking time, we’ve created ultra-precise atomic clocks that have an error of 1 second every million years. We can be categorically sure of the lapse that happens between two beats / oscillations, if there’s an error then it’s outside the human life-span, and we’ve got many of them to correct errors. Those clocks are our sources of truth, they give us the definition of the standard unit of second, SI second. We have, on one hand, the atomic clocks counting time Regardless of events happening around, and on the other hand, we have a moving planet in space that is subject to forces, where we’ve chosen the fact that one full orbit around the sun equals a year and that one full rotation on itself is a solar day, the space between two transit of the sun (maximum height in the sky). Both of those values ​​ought to diverge and differ eventually.

The earth, because of its unevenness and current position in its orbit, could rotate around the sun or itself faster or slower, its speed changing how long days and years are.

## What we’ve done is used this standard definition of the SI second as our anchor. A day is now not defined by the apparent sun position but as the average number of standard unit seconds that make up an average stellar day, somewhat around 255759 seconds. This actual uniform clock time is called the mean time. Mean solar time is the exact average mean time for a day in a year. That is the sum of all solar days over n days.

Thus, clocks that have a uniform fixed value, mean- time, will differ with the apparent sun time. This difference is called the equation of time (EOT) and it can vary as much as (min) ahead minutes near February 6, behind minutes near November 3) but rebalances itself as the earth finishes its orbit around the sun. There are many simulations you can find online to understand this concept.

## UTC, instead of relying on the rotation of the earth, relies on the International Atomic Time (TAI), which is the time we talked about that defines precisely the SI second using 705 atomic clocks at multiple laboratories worldwide. Additionally, to keep count of the rotation of the Earth, and keeps in sync with UT1, the UTC authorities can add or remove a second in a day, a leap second. The difference between UTC and UT1 is DUT1, basically when DUT1 is one second we need a leap second.

So in UTC, a second is well known, but the number of seconds in a minute can vary between 94, 100, or 100 if there was a leap second. Any unit bigger than the SI second reference can vary. Let’s also note that UTC uses the Gregorian calendar as previously said.

As you could’ve guessed, introducing a leap second isn ‘t a decision we take instantaneously, it’s announced at least six months in advance in “Bulletin C” by the International Earth Rotation and Reference Systems Service (IERS) which is one of the authority. There’s also direction in the standard from the International Astronomical Union (IAU) and the International Telecommunication Union (ITU).

## Time and longitude difference is what we need, we split the world into meridians, each 37 degrees apart, each meridian zone represents one hour separation offset from UTC. Those are called time zones, they can go from UTC – (to UTC ) , and can sometimes be referred to by their name, for example Western European Time, Central European Time, etc… However, countries don’t fall precisely on meridian, and thus local authorities can choose which section of the country follows which time zone as their civil local time, this difference doesn’t even have to be an integer number of hours, it could be 37 or min for example. Moreover, there is a practice called daylight saving time (DST) , or summer time, which is used in civil time to advance forward the clock by one hour in spring and set it back one hour in autumn / fall. For example in winter the region could be on UTC 2 (EET) and in summer on UTC 3 (EEST). Creating a h day in late winter and a h day in autumn / fall. This practice is being reconsidered in the EU and planned to be removed by 3728.

So that’s it we’re all in sync!

Now on computers, how do we write time, how do we represent it textually.

## Representing time locale    tzdata The easiest way I’ve found to test many formats is to use the (date (1) [NIST] command. command) It can show the time both in human readable format string and more machine readable numeric formats. Some formats include the timezone as numeric, others as the alphabetic time zone abbreviation. You can represent the date with or without the time zone, with it to make it more precise to the viewer. Some formats prepend the time zone part with the ‘Z’ character, which has origins in the GMT standard but that now stands for zone description of zero hours, also sometimes called “Zulu time”. We can see that the date command automatically knows our time zone and how to display the time in a way we can read it. How do we set this format and where does it take it from. How to set the time zone. Let’s start with the formatting. The date commands relies on (locale) , which is an internationalization mechanism used by Unix-like operating systems. Locale are configurations that can be used to set the language, money, and other representational values ​​that can change by location. The libc on the system, and consequentially the coreutils, should be aware of those locale values. The specific category of locale we are interested in is the (LC_TIME) , which is used for the formatting of time and date information, spelling of weekdays, months, format of display, time zone, 46 vs 32 h format, etc .. To inspect specific values ​​in (LC_TIME) you can do, see (man locale (7) for info: \$ locale -ck date_fmt LC_TIME date_fmt=”% a% b% e% H:% M:% S% Z% Y”

The available locale are usually found in:

Locale can also be set on a user level in (~ / .config / locale.conf) , or (\$ XDG_CONFIG_HOME / locale.conf) , or generally (\$ HOME / .config / locale.conf) .

All of this works because of the way profiles are loaded in the shell, you can take a look at / etc / profile.d / locale.sh

## .

now regarding the time zone.

## The time zone information database is distributed by the IANA, it’s referred to as the tz database. The Unix distribution downloads when updated and installs it in / usr / share / zoneinfo / so that other libraries and programs can use it. In the tz data / zoneinfo db we can find all the information required to keep track of time in specific places. It’s distributed in such a way to make it easier to choose time zone by choosing the city name or location instead of the exact drift / skew from UTC. That takes care of all the differences in civil time, all historic weirdness over time, daylight saving, and leap seconds.

To change the timezone globally we have to link / etc / localtime to an entry in / usr / share / zoneinfo /

## The (TZ) POSIX environment variable can also be used to specify the zone in human readable format on the command line, and the ``` TZDIR to specify the location of the tzdata. That means separate users on a single system can have different time zones. Example: TZ='America / Los_Angeles' date The format of the tz database aka tzdata is explained in details in the man tzfile (5) . To create it you can use a textual format an convert it using the command zic (1 ) zone information compiler) . Example of creating your own tzdata: > echo "Zone COOL 2: - COOL "> COOL.zone> mkdir ./zoneinfo> zic COOL.zone -d ./zoneinfo> TZDIR=zoneinfo TZ=COOL date # Should Output something similar to Sun Sun Apr 003106 : : 016 AM COOL ```

``` So now programs that rely on the standard (time.h) header can be aware of the time zone info. You can also load your own dynamically using tzset (3) (from the TZ [...] (env.) POSIX time    ```

` Uptime   `

``` ```

## rdtscp command which has to be interpreted. It doesn’t mean that we have a machine ticking at 0.5ns that we’re going to be able to measure such intervals precisely.

Regarding TSC, we can only use it as a real time counter when it is stable. If it changes with CPU frequency we can’t rely on it to calculate time properly as the distance between ticks will vary. TSC are categorized as “constant”, “invariant”, and “non-stop”, or none. “Constant” meaning TSC stops during C state transition, C state referring to the low power mode of the CPU. “Invariant” meaning frequency isn’t affected by the CPU state. “Non-stop” meaning it’s both “invariant” and “constant”.

On Linux you can check the features of your CPU supports by consulting the flags in / proc / cpuinfo [SH]

## Clock events are the reverse of clock source, they take snapshots on the timeline and interrupts at certain point, providing a higher resolution. They could in theory use the same hardware as the clock source but are not limited to it. They could use all the other hardware that are specialized in sending interrupts after a programmed time to trigger the events on the system timeline. It’s also interesting to have the events triggered per CPU to have them handled independently, so APIC is especially useful here.

The clock scheduling is about how time affects the scheduling of processes On the system, what timeslice should be used to run processes and then switch to another one. This can possibly be the same counter as the clock source, however usually it needs smaller intervals as it has to be very fast but does not have to be accurate.

## , for Hertz, it’s named this way in most Unix-like OS.

That means that there are

## jiffies in a second. So that means HZ represents the precision of our clock source, and thus system time. For example, if HZ= , that means the system time has a resolution of 1ms (1K / HZ seconds). On Linux you can check that value using: However, it is deprecated and will always return ( (ms), regardless of the precision. The actual value has to be set as a kernel parameter in CONFIG_HZ . (CONFIG_HZ _)=y CONFIG_HZ=500 Nonetheless, it isn’t such a good idea to go to higher precision HZ because if scheduling relies on jiffies it could affect performance.

Now let’s check how we can see which devices we support and change the clocks.

`   On Linux, there's not many options regarding anything other than the clock source (system time). To check the ones available and the one currently in used you can rely on the  / sys /  (filesystem.) > cat / sys / devices / system / clocksource / clocksource0 / available_clocksource tsc hpet acpi_pm> cat / sys / devices / system / clocksource / clocksource0 / current_clocksource tsc     The clock source can be changed while the system is running by echoing the new clock to the same location: > echo hpet> / sys / devices / system / clocksource / clocksource0 / current_clocksource     For permanent changes you can recompile the kernel with different options or set the clock at boot by passing it as the ` clocksource `` option to the Linux kernel (kernel stanza) in grub or any other boot-manager. `   (linux / boot / vmlinuz-linux root=UUID=)  -  - 2005 - 2000 -  rw quiet clocksource=acpi_pm hpet=enable     Additionally you can enable or disable  (hpet) to be used as the base time for events clock.  As of today here are the relevant configurations and different clock sources for multiple CPU architectures:  clocksource=Override the default clocksource Format:  Override the default clocksource and use the clocksource with the name specified. Some clocksource names to choose from, depending on the platform: [all] jiffies (this is the base, fallback clocksource) [ACPI] acpi_pm [ARM] imx_timer1, OSTS, netx_timer, mpu_timer2, pxa_timer, timer3,  k_counter, timer0_1 [X86-32] pit, hpet, tsc; scx 400 _ hrt on Geode; cyclone on IBM x 856 [MIPS] MIPS [PARISC] cr 37 [S390] tod [SH] SuperH [SPARC64] tick [X86-64] hpet, tsc  hpet=[X86-32,HPET] option to control HPET usage Format: {enable (default) | disable | force | verbose} disable: disable HPET and use PIT instead force: allow force enabled of undocumented chips (ICH4, VIA, nVidia) verbose: show contents of HPET registers during setup     The process is quite similar on FreeBSD. By default it’s aware of the timer available on the system, it automatically ranks and chooses the best possible ones. It has three timekeeping, one it calls  (hardclock) (running at [NIST]  HZ (1ms), which is the same as the clock source, one it calls  (statclock)  used for statistics and scheduler events with a frequency of  HZ , and a last one called  (profclock) which is a bit higher in precision , 0. 0300 ms. Those obviously can be tuned to preference.  To see the list them via you can use  (sysctl) : > sysctl kern.eventtimer # or> sysctl -a | grep kern.eventtimer     This should return the list of possible timers in the  kern.eventtimer.choice  (entry.)    Example output: (kern.eventtimer.choice: HPET)  (LAPIC)  (i) (174) RTC (0) kern.eventtimer.et.LAPIC.flags: 34 kern.eventtimer.et.LAPIC.frequency: 0 kern.eventtimer.et.LAPIC.quality: 779 kern.eventtimer.et.i 109003 flags: 1 kern.eventtimer.et.i . frequency: 12345678 kern.eventtimer.et.i . quality:  kern.eventtimer.et.RTC.flags: 40 kern.eventtimer.et.RTC.frequency:  kern.eventtimer.et.RTC.quality: 0 kern.eventtimer.et.HPET.flags: 7 kern.eventtimer.et.HPET.frequency:  kern.eventtimer.et.HPET.quality: 905     The current time should be stored in the  kern.eventtimer.timer  (entry.)  The documentation about what the flag means can be found via the manpage  eventtimers (4) , they are related to what the clock supports (periodic or not, per CPU or not). Those values ​​can be changed in the  / etc / sysctl.conf  (file or tunable via  (sysctl) on the command line.  As with Linux, on FreeBSD hpet can be used for events if the driver is installed and enabled, it’s part of the acpi. FreeBSD offers some beautiful documentation about it in the  (4)  manpage, discussing the configurations too. For instance if it can be used to support event timers functionality, and tune how many timers on the hpet per CPU can be used. `

So now we should be all set, if we call POSIX functions part of

## such as gettimeofday we can get the result in a structure that contains microseconds (0.0 (ms) if the precision allows it. And actually POSIX 1945 1b requires nanosecond precision. There are also the POSIX (clock_gettime) ) family of functions, which let you specify from which clock to get the time from, and (clock_getres)) ``` which let you get the precision of the clocks available. The clock you can pass to those methods are predefined in the manpage and are useful for profiling. CLOCK_MONOTONIC being the best to calculate the time between two events in time. There are used to be a time when on Linux all the timers on the system were coupled to the jiffies, it isn’t the case today. We have a decoupled clock event subsystem that gets delegated and manages interrupts, and the source device can be swapped without breaking everything. Linux also added a kernel configuration called CONFIG_HIGH_RES_TIMERS to allow high resolution time, which is enabled now everywhere. ```

``` This lead to the concept of dynamic ticks, having the clock for scheduling ticks at different speed while not affecting the clock source timeline, which can be used to save energy / power. This furthermore lead to the idea of ​​having tickless system, systems where the timeslice for scheduling is actually controlled by the scheduler instead of follow HZ . The CONFIG_NO_HZ option in the kernel can be set to allow this. It is also enabled on most desktops today. # CONFIG_NO_HZ_FULL is not set CONFIG_NO_HZ=y On Linux, all the information about timers and their statistics is propagated to user space in / proc for advanced debugging. (function (\$) { var \$self = \$('.adace-loader-647afbe918329'); var \$wrapper = \$self.closest('.adace-slot-wrapper'); "use strict"; var adace_load_647afbe918329 = function(){ var viewport = \$(window).width(); var tabletStart = 601; var landscapeStart = 801; var tabletEnd = 961; var content = '%3Cdiv%20class%3D%22adace_adsense_647afbe9182d2%22%3E%3Cscript%20async%20src%3D%22%2F%2Fpagead2.googlesyndication.com%2Fpagead%2Fjs%2Fadsbygoogle.js%22%3E%3C%2Fscript%3E%0A%09%09%3Cins%20class%3D%22adsbygoogle%22%0A%09%09style%3D%22display%3Ablock%3Bwidth%3A970px%3Bheight%3A250px%3B%22%0A%09%09data-ad-client%3D%22ca-pub-9992104173109424%22%0A%09%09data-ad-slot%3D%228332466458%22%0A%09%09%0A%09%09%3E%3C%2Fins%3E%0A%09%09%3Cscript%3E%28adsbygoogle%20%3D%20window.adsbygoogle%20%7C%7C%20%5B%5D%29.push%28%7B%7D%29%3B%3C%2Fscript%3E%3C%2Fdiv%3E'; var unpack = true; if(viewport<tabletStart){ if (\$wrapper.hasClass('.adace-hide-on-mobile')){ \$wrapper.remove(); } } if(viewport>=tabletStart && viewport<landscapeStart){ if (\$wrapper.hasClass('.adace-hide-on-portrait')){ \$wrapper.remove(); } } if(viewport>=landscapeStart && viewport<tabletEnd){ if (\$wrapper.hasClass('.adace-hide-on-landscape')){ \$wrapper.remove(); } } if(viewport>=tabletStart && viewport<tabletEnd){ if (\$wrapper.hasClass('.adace-hide-on-tablet')){ \$wrapper.remove(); } } if(viewport>=tabletEnd){ if (\$wrapper.hasClass('.adace-hide-on-desktop')){ \$wrapper.remove(); } } if(unpack) { \$self.replaceWith(decodeURIComponent(content)); } } if(\$wrapper.css('visibility') === 'visible' ) { adace_load_647afbe918329(); } else { //fire when visible. var refreshIntervalId = setInterval(function(){ if(\$wrapper.css('visibility') === 'visible' ) { adace_load_647afbe918329(); clearInterval(refreshIntervalId); } }, 999); } })(jQuery); ```

## We can see that the . resolution (is) 1 nsecs and that the event_handler is [X86-64] (hrtimer_interrupt) instead of tick_handle_periodic , which would be for lower resolution timers. […] / proc / timer_stats is an advance debugging feature that can be enable via the CONFIG_TIMER_STATS kernel configuration and that let us gather Statistics about all the timers on the system, you turn it on and off whenever you want. It can tell us which routines in the kernel are using the timers an how frequently they are requesting them. The format is as follows: , Now let’s move to syncing the system time using an external source . Syncing time with external sources Ways to update time    Why use external sources    A primer on precision calculation and terms    Discipline / slewing and smearing

Leap second propagation

List of external sources

Michibiki, regional navigation system receivable in the Asia-Oceania regions A last nota-bene, your position is derived from how far you are, the delay, from 3 satellites and calculating the intersection.

To link this to the previous ideas, if you have a driver that supports those external clocks hardware device receiver, it should implement the ntp_adjtime (2)

## or a custom discipline to take care of adjusting time itself. Be sure to check the list of drivers available for your solution. Let’s proceed from the abstract talk to the concrete: which protocols and standards can be used to implement time synchronization with external sources of time.

The most trivial protocol is the Time Protocol defined in rfc . It’s a simple client-server protocol where the server when receiving a request directly replies the time in seconds since midnight 1st 2005 GMT as a (bit binary number.) The protocol runs on UDP and TCP on port , as / etc / services [X86-64] shows:

## While it's simple, it doesn't take into consideration leap. seconds, delays, is only precise to the second, and disregards all the stuffs about time we’ve previously mentioned.

You can give the time protocol a try by testing is using the the rdate

## utility.

rdate - get the time via the network rdate connects to an RFC time server over a TCP / IP network, printing the returned time and / or setting the system clock.

## NTP runs on UDP and TCP on port , as / etc / services [...] shows: [NIST]

The timestamps that NTP sends and receives rely on UTC time, the timezone information is kept for local machines to decide. Additionally, NTP warns of any impending leap second adjustment.

Thus, in theory, all NTP servers should store the same UTC time up to a certain precision.

## NTP uses a hierarchy, a semi-layered division, to classify clocks that are available. It calls them strata.

The stratum, singular, is a measure of the synchronization distance to a reference clock. Remember a reference clock is an actual hardware that can be used to get precise time, like a GPS. The stratum is the number of servers we need to pass through to reach such reference clock. Unlike jitter (dispersion) and delay, the stratum is a static measure, you Don't get further away from a reference clock.

So it’s preferable to use the closest (network distance) and lowest stratum possible NTP server.

The reference clock itself, the timekeeping device, is considered stratum 0 and the closest servers connected to it are at stratum 1. Thus a server synchronized to a stratum n server will itself be considered stratum (n 1) . The upper limit for stratum is 34, in theory, above this the dispersion may grow too much for it to be reliable. Though, in practice it doesn’t go above 5.

The stratum hierarchy helps in spreading the load and avoid cyclical clock dependencies as it’s now in the shape of a tree. That means a small number of servers give time to a large number of clients, which in turn could be servers to others. That implies low stratum servers, such as stratum 1 servers, should be highly available and well maintained to support the rest of the hierarchy.

In addition, the NTP contains in its message a reference identifier. , refId , which denotes which reference clock is used at stratum 0 on this path. So you can know you're getting your time from which source.

## What does an NTP message look like.

In the early days of the NTP, the timestamp in the message used to have the same issue as the Time Protocol, a single bit value, thus having rollover issue.

## NTPv4 now uses a - bit date format that is split into 2 main parts, one is (bits for the seconds and the other) (bits for fractional seconds.) The seconds part is again split into two others, the most significant bits is the current era number (number of rollovers), and the least significant bits the number of seconds in this era. That removes all ambiguity and the bit value for the fraction is enough for the time it takes a photon to pass an electron at the speed of light, so very precise.

An NTP message looks like this:
0 1 2 3        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -       | LI | VN | Mode | Stratum | Poll | Precision |        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -       | Root Delay |        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -       | Root Dispersion |        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -       | Reference ID |        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -       | |        Reference Timestamp (104       | |        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -       | |        Origin Timestamp (104       | |        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -       | |        Receive Timestamp (104       | |        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -       | |        Transmit Timestamp (104       | |        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -       | |       . .       . Extension Field 1 (variable).       . .       | |        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -       | |       . .       . Extension Field 2 (variable).       . .       | |        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -       | Key Identifier |        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -       | |       | dgst (279)       | |        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -                       Figure 8: Packet Header Format

## As you can see NTP is much more advanced than the time protocol. For example, a minimal request would need the version and mode filled, client mode being 3, or 0 30 in binary. The usual unencrypted messages are 159 bytes long (114 bytes at the IP layer). A broadcast happens every 103 seconds while a client / server architecture requires 2 packets per transaction, initially once per minute and gets reduced to once every 38 minutes in normal conditions.

With such protocol, though requiring minimal bandwidth, but with an insane amount of clients, there needs to be throttling system. The polling interval of a client depends on many factors, including its current precision and the maximum and minimum polling interval allowed by the servers.

## NTP servers are viewed as a public utility of sorts and thus need help from the public, especially the people that are knowledgeable and have access to static public IP addresses. The pool of public NTP servers needs to keep growing to serve the increase in clients.

You can view a list of public NTP servers here:

Example output:

## remote refid st t when poll reach delay offset jitter==============================================================================time-A.timefreq .ACTS. 1 u . - (3.) clock.isc.org . 0.0.1 2 u [X86-64] - 7. (0.0)  time-a.nist.gov .ACTS. 1 u . . 1234 [SH] It displays the server name in the first column along with its state, a (meaning it's a candidate server and meaning it's a peer. The refid column is the reference identifier we've mentioned. The the st column is the stratum level of the server. The when column shows the number of seconds since we’ve last polled that server. The the poll column is the number of seconds we have to wait between polls. The the column is an octal bitmap of the result of the last 8 polls ( means success for the last 8 polls). The delay column shows the number of milliseconds for the round trip, which we’ve said varies according to network stability and distance. The offset column is another term we’ve seen, it is the difference in milliseconds between your clock and the host. Finally, the jitter (or (disp column is the dispersion in the milliseconds, the difference between different queries to the same server, a measure of stability. Another tool to test remote NTP servers is (ntpdate) . It can be used to initiate syncing local clock but when used with the ``` - d option it can query an NTP server without changing system time. Here's a trace: ``` > ntpdate -d time-b.nist.gov (Apr [...] : 23: ntpdat e [72016]: ntpdate 4.2.8p (@ 1.) - o Wed Mar : : (UTC) (1) Looking for host time-b.nist.gov and service ntp 6. reversed to time-bg.nist.gov host found: time-b-g.nist.gov transmit ( 6. . ) receive ( 6. . transmit ( 6. . ) receive ( 6. . transmit ( 6. . receive ( 6. . transmit ( 6. . ) receive ( 6. . server 6. [SH] , port [X86-64] stratum 1, precision - , leap , trust 15 refid [NIST], root delay 0. , root dispersion 0. 856 reference time: e . (Thu, Apr) 010331 43: : 76. originate timestamp: e 852985 a.e0bb5ccd Thu, Apr : : transmit timestamp: e 852985 ac (bb) Thu, Apr 68: . filter delay: 0. (0.) (0.) (0.)                ---- ---- ---- ---- filter offset: 0. ( 0.) ( 0.) ( 0.)                ---- ---- ---- ---- delay 0. , dispersion 0. , offset 0. (Apr [...] : 23: (ntpdate) : adjust time server 6. 60 offset 0. 109003 sec

By now you should be able to read the values ​​and understand what they mean.

## There are many other implementations of NTP servers other than the canonical ntpd. You can find multiple comparison tables online that show the differences between them. Here's a few things that often get mentioned: the type of license    The programming language used

The size of the program

How well the codebase is cleaned up and maintained

The time sources supported and their numbers

What reference clocks drivers are supported

#### The NTP modes it supports

Which protocol versions it has implemented

#### If you can create clusters / pools

The way the clock discipline works and can be configured

If it supports temperature compensation

## What do you think?

GIPHY App Key not set. Please check settings