Skip to main content
p. 181

7.5 Setting the Time

Unix machines depend on accurate timekeeping. The kernel maintains the system clock, which is the clock consulted when you run commands like date. You can also set the system clock using the date command, but it’s usually a bad idea to do so because you’ll never get the time exactly right. Your system clock should be as close to the correct time as possible.

PC hardware has a battery-backed real-time clock (RTC). The RTC isn’t the best clock in the world, but it’s better than nothing. The kernel usually sets its time based on the RTC at boot time, and you can reset the system clock to the current hardware time with hwclock. Keep your hardware clock in Universal Coordinated Time (UTC) in order to avoid any trouble with time zone or daylight saving time corrections. You can set the RTC to your kernel’s UTC clock using this command:

# hwclock --systohc --utc

Unfortunately, the kernel is even worse at keeping time than the RTC, and because Unix machines often stay up for months or years on a single p. 182 boot, they tend to develop time drift. Time drift is the current difference between the kernel time and the true time (as defined by an atomic clock or another very accurate clock).

You shouldn’t try to fix time drift with hwclock because time-based system events can get lost or mangled. You could run a utility like adjtimex to smoothly update the clock based on the RTC, but usually it’s best to keep your system time correct with a network time daemon (see Section 7.5.2).

7.5.1 Kernel Time Representation and Time Zones​

The kernel’s system clock represents the current time as the number of seconds since 12:00 midnight on January 1, 1970, UTC. To see this number at the moment, run:

$ date +%s

To convert this number into something that humans can read, user-space programs change it to local time and compensate for daylight saving time and any other strange circumstances (such as living in Indiana). The local time zone is controlled by the file /etc/localtime. (Don’t bother trying to look at it; it’s a binary file.)

The time zone files on your system are in /usr/share/zoneinfo. You’ll find that this directory contains a lot of time zones and aliases for time zones. To set your system’s time zone manually, either copy one of the files in /usr/share/zoneinfo to /etc/localtime (or make a symbolic link) or change it with your distribution’s time zone tool. The command-line program tzselect may help you identify a time zone file.

To use a time zone other than the system default for just one shell session, set the TZ environment variable to the name of a file in /usr/share/zoneinfo and test the change, like this:

$ export TZ=US/Central
$ date

As with other environment variables, you can also set the time zone for the duration of a single command like this:

$ TZ=US/Central date

7.5.2 Network Time​

If your machine is permanently connected to the internet, you can run a Network Time Protocol (NTP) daemon to maintain the time using a remote server. This was once handled by the ntpd daemon, but as with many other services, systemd has replaced this with its own package, named timesyncd. Most Linux distributions include timesyncd, and it’s p. 183 enabled by default. You shouldn’t need to configure it, but if you’re interested in how to do it, the timesyncd.conf(5) manual page can help you. The most common override is to change the remote time server(s).

If you want to run ntpd instead, you’ll need to disable timesyncd if you’ve got it installed. Go to https://www.ntppool.org/ to see the instructions there. This site might also be useful if you still want to use timesyncd with different servers.

If your machine doesn’t have a permanent internet connection, you can use a daemon such as chronyd to maintain the time during disconnections.

You can also set your hardware clock based on the network time in order to help your system maintain time coherency when it reboots. Many distributions do this automatically, but to do it manually, make sure that your system time is set from the network and then run this command:

# hwclock --systohc –-utc