Note
Most of this document is pretty old (from 2002). These days (2012) most devices are smoothly using NTP by default and perfect time is expected. Still if a computer’s time comes up wrong, this might still provide some insight.

What Time Is It Really?

The US Naval Observatory knows. Call: (202) 762 - 1401

Linux Time Overview

For all intents and purposes, there are 2 clocks to worry about with Linux. The first is the Hardware Clock. This is the clock on a motherboard chip that keeps time even when the machine is powered off. It is horribly inaccurate, but rumor has it that it is usually off in a predictable way i.e. a constant skew.

The other clock is the virtual System Clock. Linux asks the Hardware Clock chip what time it is on power up and then keeps track of the time itself with software. It does this using a periodic interrupt from an accurate timer chip (not the Hardware Clock’s chip). It’s a bit like using a sundial and a digital egg timer to keep track of time. When the sun comes out (power up) you can get a half-assed reading of the time and from then on, use the accurate timer and some math since the accurate timer has no sense of the real time.

Clock Setting The Clumsy Way

Apparently, this System Clock is rather accurate (i.e. good enough) at keeping time. The real trick is relating that to True Time. This involves keeping the Hardware Clock happy. My old strategy has been to simply catch the system at startup and set the Hardware Clock using the BIOS utility. Linux then gets the Hardware Clock’s time and everything’s fine from then on. But this means that every time I reboot, the clock is set to an ever diverging bogus time. The one advantage of this scheme besides simplicity is that it does not disturb anything during the change. Changing time can upset some Linux processes that might, for example, be putting time stamps on things. Setting the Hardware Clock in the BIOS independent of the Linux system is especially good for annoying things like Daylight Savings Time where the change will be abrupt.

Setting The System Clock

To set the system clock, use the "date" command. The big problem with this idea is that unless you are somehow setting the system time to the hardware clock, your time change will only last until the next time Linux powers when the system time will revert back to the hardware clock. But if you have your heart set on doing this, the format is MMDDhhmm[[CC]YY][.ss], like so: # date 103113492002.55 ; date Thu Oct 31 13:49:55 PST 2002

Setting The Hardware Clock

To change the Hardware Clock, you can use the motherboard’s BIOS utility at startup, but if you miss that opportunity, there is still hope. The "hwclock" command handles issuse relating to the Hardware Clock from Linux. This basically amounts to checking it and setting it, though there are some fancy things it does too.

hwclock has a "set" command that uses a "date" option’s argument. The date (aka time) is specified using the date input format of GNU Shell Utilities. I mention this because it’s rather amazing in the formats it can deal with and good documentation can be found with info sh-utils. Here is the format that I use for setting the hardware clock. This sets to 2:21pm on Halloween.

# hwclock --set --date "02-10-31 14:21:30"

And to check your work, you could reboot and look at the BIOS or do this:

# hwclock --show

Here is an example of the fact that the Hardware Clock and the System Clock are not really a part of each others personal space:

# date 103113212002.30; hwclock --set --date "02-10-31 14:21:30"; hwclock --show; date
Thu Oct 31 13:21:30 PST 2002
Thu Oct 31 14:21:32 2002  -0.494324 seconds
Thu Oct 31 13:21:31 PST 2002

Accurate Time Strategies - Hardware Clock

There are basically 2 ways to approach accurate computer time. The first is to make the best of the Hardware Clock. This implies the fact that the Hardware Clock chip may be bad, but it is consistently bad. In other words, it loses or gains a definite amount of time every day with not much variation. If this isn’t true (say with a very dead CMOS battery) then this is not a good approach. The idea is that whenever you set the hardware clock it makes a note as to when you are setting it. It also compares what time you’re setting it to (the True Time) vs. what it has slacked off to. This is the skew. Since it is recording when these resets are made, it knows the skew per time since last set. This means that you have a very accurate knowledge of how much time the hardware clock gians or loses per day. When Linux boots, it’s all smoke and mirrors anyway when it comes to setting the system clock; why not do some calculation to see what the time is compensated for the slow or fast Hardware Clock?

It turns out that the "hwclock" command is set up to help out with this. The basic strategy seems to be to use hwclock to set the hardware clock from a known good source of accurate time. After doing this a few times, hwclock will have recorded how the Hardware Clock’s error propagates. Then using the hwclock’s --adjust option, the Hardware Clock is conpensated by the known drift. This command can be put in startup scripts and everything should be a lot better than nothing.

This is all theoretical since I’m moving right along to a more interesting solution….Read on…

Accurate Time Strategies Part II - External Reference

In the analogy of using a sundial and an egg timer to keep time, there is an obvious improvement. Well, there are two. First you could get some very accurate time hardware which would be analogous to buying a watch and scrapping the sundial and timer. The problem here is that such hardware (2002) is still expensive.

The next best thing is to scrap the sundial and ask someone who’s wearing a watch what time it is. This means that we can totally forget about the stupid Hardware Clock and its terrible performance record. We’ll still need to use our timer, but Linux is good at that and it’s accurate. Besides, we can ask watch wearer for a sanity check every so often. For networked computers, our watch wearer reference is a network time server.

The classic way to use an external time reference is the Network Time Protocol or NTP. The standard Unix way of employing it for time keeping purposes is the program ntpd which can be found at www.ntp.org.

Install the ntp package per the normal unix way. Now you need to set up a configuration file called "/etc/ntp.conf". This is a relatively simple thing. Mine looks like this:

#/etc/ntp.conf
#cxe- Config file for Network Time Protocol Daemon (ntpd)
#cxe- Thu Oct 31 16:24:04 PST 2002

#cxe- the time sever we want to sync with
server ntp.ucsd.edu

#cxe- file containing error information to avoid constant refiguring
driftfile /etc/ntp.drift

Then run ntpd. To see if everything is working, you can use the -d option for a running foreground look at the action.

I also put ntpd in my /etc/init.d/boot.local file to kick it off on start up.

Available Public Time Servers

Here’s a good one for people in San Diego:

ntp.ucsd.edu. is an alias for bigben.ucsd.edu.
bigben.ucsd.edu. has address 132.239.1.6

Use ntptrace to find out about a time servers credentials:

# ntptrace ntp.ucsd.edu
bigben.ucsd.edu: stratum 2, offset 3597.812941, synch distance 0.01761
time.sdsc.edu: stratum 1, offset 3597.824951, synch distance 0.00359, refid 'WWVB'

Note: Looks like ntptrace is not really returning anything recently (2018) with any time server I’ve checked. Maybe it’s a broken tool, abused by bad guys.

Try ntpq.

$ ntpq -p time.ucsd.edu
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
 temp-solaris.sd .INIT.          16 u    - 1024    0    0.000    0.000   0.000
 132.239.254.139 .INIT.          16 s    - 1024    0    0.000    0.000   0.000
 172.16.18.5                     16 u 233d 1024    0    0.000    0.000   0.000
 b-core-6509--m- .INIT.          16 s    - 1024    0    0.000    0.000   0.000
*nodem-gps-clock .GPS.            1 u  258 1024  377    0.000    0.000   0.000

Fixing NTP Problems

Sometimes your ntpd server has crashed and your clock is way off. The best way I’ve found to fix that is the following. First, stop ntp so things don’t get confused while you fix the time.

# /etc/init.d/ntpd stop
 * Stopping ntpd ... [ ok ]

Next fix your /etc/ntp.conf file so that the server line says something you think is likely to work for you.

# grep ^server /etc/ntp.conf
server time.ucsd.edu

Now fix your time manually using NTP.

# ntpdate time.ucsd.edu
19 Sep 15:00:23 ntpdate[16421]: step time server 132.239.1.5
offset 25031.961931 sec

Hopefully that’s what time it really is now. Resume your daemon.

# /etc/init.d/ntpd start
* Starting ntpd ...                    [ ok ]

Public NTP Servers

These may be a bad idea, but they’re a starting point if you don’t want to use your system’s default pool.

  • time.ucsd.edu - San Diego

  • clock.nyc.he.net

  • bonehed.lcs.mit.edu

  • tick.utoronto.ca

  • ntp.your.org

  • ntp1.torix.ca, ntp3.torix.ca - Toronto

  • pool.ntp.org - (pool)

  • ntp.ubuntu.com - (pool)

  • time.apple.com - ?

  • clock.trit.net

  • time.centos.org