Linux Professional Institute Learning Logo.
Skip to main content
  • Home
    • All Resources
    • LPI Learning Materials
    • Become a Contributor
    • Publishing Partners
    • Become a Publishing Partner
    • About
    • FAQ
    • Contributors
    • Roadmap
    • Contact
  • LPI.org
108.1 Lesson 1
Topic 105: Shells and Shell Scripting
105.1 Customize and use the shell environment
  • 105.1 Lesson 1
  • 105.1 Lesson 2
  • 105.1 Lesson 3
105.2 Customize or write simple scripts
  • 105.2 Lesson 1
  • 105.2 Lesson 2
Topic 106: User Interfaces and Desktops
106.1 Install and configure X11
  • 106.1 Lesson 1
106.2 Graphical Desktops
  • 106.2 Lesson 1
106.3 Accessibility
  • 106.3 Lesson 1
Topic 107: Administrative Tasks
107.1 Manage user and group accounts and related system files
  • 107.1 Lesson 1
  • 107.1 Lesson 2
107.2 Automate system administration tasks by scheduling jobs
  • 107.2 Lesson 1
  • 107.2 Lesson 2
107.3 Localisation and internationalisation
  • 107.3 Lesson 1
Topic 108: Essential System Services
108.1 Maintain system time
  • 108.1 Lesson 1
  • 108.1 Lesson 2
108.2 System logging
  • 108.2 Lesson 1
  • 108.2 Lesson 2
108.3 Mail Transfer Agent (MTA) basics
  • 108.3 Lesson 1
108.4 Manage printers and printing
  • 108.4 Lesson 1
Topic 109: Networking Fundamentals
109.1 Fundamentals of internet protocols
  • 109.1 Lesson 1
  • 109.1 Lesson 2
109.2 Persistent network configuration
  • 109.2 Lesson 1
  • 109.2 Lesson 2
109.3 Basic network troubleshooting
  • 109.3 Lesson 1
  • 109.3 Lesson 2
109.4 Configure client side DNS
  • 109.4 Lesson 1
Topic 110: Security
110.1 Perform security administration tasks
  • 110.1 Lesson 1
110.2 Setup host security
  • 110.2 Lesson 1
110.3 Securing data with encryption
  • 110.3 Lesson 1
  • 110.3 Lesson 2
How to get certified
  1. Topic 108: Essential System Services
  2. 108.1 Maintain system time
  3. 108.1 Lesson 1

108.1 Lesson 1

Certificate:

LPIC-1 (102)

Version:

5.0

Topic:

108 Essential System Services

Objective:

108.1 Maintain system time

Lesson:

1 of 2

Introduction

Accurate timekeeping is absolutely crucial for modern computing. The implementation of keeping time, however, is surprisingly complex. The practice of keeping time seems trivial to an end-user, but the system needs to be able to handle many idiosyncrasies and edge cases intelligently. Consider that time zones are not static, but may be changed by an administrative or political decision. A country may choose to stop observing Daylight Savings Time. Any program must be able to handle those changes logically. Fortunately for system administrators, the solutions for timekeeping on the Linux operating system are mature, robust and usually work without much interference.

When a Linux computer boots up, it starts keeping time. We refer to this as a system clock, since it is updated by the operating system. In addition, modern computers will also have a hardware or real time clock. This hardware clock is often a feature of the motherboard and keeps time regardless if the computer is running or not. During boot, the system time is set from the hardware clock, but for the most part these two clocks run independently of each other. In this lesson we will be discussing methods of interacting with both the system and hardware clocks.

On most modern Linux systems, system time and hardware time are synchronised to network time, which is implemented by the Network Time Protocol (NTP). In the vast majority of cases, the only configuration a normal user will be required to do is to set their time zone and NTP will take care of the rest. However, we will cover some ways of working with time manually and the specifics of configuring network time will be covered in the next lesson.

Local Versus Universal Time

The system clock is set to Coordinated Universal Time (UTC), which is the local time at Greenwich, United Kingdom. Usually a user wants to know their local time. Local time is calculated by taking UTC time and applying an offset based on time zone and Daylight Savings. In this way, a lot of complexity can be avoided.

The system clock can be set to either UTC time or local time, but it is recommended that it also be set to UTC time.

Date

date is a core utility which simply prints local time:

$ date
Sun Nov 17 12:55:06 EST 2019

Modifying the options of the date command will change the format of the output.

For example, a user can use date -u to view the current UTC time.

$ date -u
Sun Nov 17 18:02:51 UTC 2019

Some other commonly-used options will return the local time in a format which adheres to an accepted RFC format:

-I

Date/time in ISO 8601 format. Appending date (-Idate) will limit the output to date only. Other formats are hours, minutes, seconds and ns for nanoseconds.

-R

Returns date and time in RFC 5322 format.

--rfc-3339

Returns date and time in RFC 3339 format.

The format of date can be customized by the user with sequences specified in the man page. For example, the current time can be formatted as Unix time thusly:

$ date +%s
1574014515

From date 's man page we can see that %s refers to Unix time.

Unix time is used internally on most Unix-like systems. It stores UTC time as the number of seconds since Epoch, which has been defined as January 1st, 1970.

Note

The number of bits required to store Unix time at the present moment is 32 bits. There is a future issue when 32 bits will become insufficient to contain the current time in Unix format. This will cause serious issues for any 32-bit Linux systems. Fortunately, this will not occur until January 19, 2038.

Using these sequences, we are able to format date and time in almost any format required by any application. Of course, in most cases it is far preferable to stick with an accepted standard.

Additionally, date --date can be used to format a time that is not the current time. In this scenario, a user can specify the date to be applied to the system using Unix time for example:

$ date --date='@1564013011'
Wed Jul 24 20:03:31 EDT 2019

Using the --debug option can be very useful for ensuring that a date can be successfully parsed. Observe what happens when passing a valid date to the command:

$ date --debug --date="Fri, 03 Jan 2020 14:00:17 -0500"
date: parsed day part: Fri (day ordinal=0 number=5)
date: parsed date part: (Y-M-D) 2020-01-03
date: parsed time part: 14:00:17 UTC-05
date: input timezone: parsed date/time string (-05)
date: using specified time as starting value: '14:00:17'
date: warning: day (Fri) ignored when explicit dates are given
date: starting date/time: '(Y-M-D) 2020-01-03 14:00:17 TZ=-05'
date: '(Y-M-D) 2020-01-03 14:00:17 TZ=-05' = 1578078017 epoch-seconds
date: timezone: system default
date: final: 1578078017.000000000 (epoch-seconds)
date: final: (Y-M-D) 2020-01-03 19:00:17 (UTC)
date: final: (Y-M-D) 2020-01-03 14:00:17 (UTC-05)

This can be a handy tool when troubleshooting an application that generates a date.

Hardware Clock

A user may run the hwclock command to view the time as maintained on the real-time clock. This command will require elevated privileges, so we will use sudo to call the command in this case:

$ sudo hwclock
2019-11-20 11:31:29.217627-05:00

Using the option --verbose will return more output which might be useful for troubleshooting:

$ sudo hwclock --verbose
hwclock from util-linux 2.34
System Time: 1578079387.976029
Trying to open: /dev/rtc0
Using the rtc interface to the clock.
Assuming hardware clock is kept in UTC time.
Waiting for clock tick...
...got clock tick
Time read from Hardware Clock: 2020/01/03 19:23:08
Hw clock time : 2020/01/03 19:23:08 = 1578079388 seconds since 1969
Time since last adjustment is 1578079388 seconds
Calculated Hardware Clock drift is 0.000000 seconds
2020-01-03 14:23:07.948436-05:00

Note the Calculated Hardware Clock drift. This output can tell you if system time and hardware time are deviating from one another.

timedatectl

timedatectl is a command that can be used to check the general status of time and date, including whether or not network time has been synchronised (Network Time Protocol will be covered in the next lesson).

By default timedatectl returns information similar to date, but with the addition of the RTC (hardware) time as well as the status of the NTP service:

$ timedatectl
               Local time: Thu 2019-12-05 11:08:05 EST
           Universal time: Thu 2019-12-05 16:08:05 UTC
                 RTC time: Thu 2019-12-05 16:08:05
                Time zone: America/Toronto (EST, -0500)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

Setting Time Using timedatectl

If NTP is unavailable, it is recommended to use timedatectl rather than date or hwclock to set time:

# timedatectl set-time '2011-11-25 14:00:00'

The process is similar to that of date. The user can also set time independent of date using the format HH:MM:SS.

Setting Timezone Using timedatectl

timedatectl is the preferred way of setting the local time zone on systemd based Linux systems when no GUI exists. timedatectl will list possible time zones and then the time zone can be set using one of these as an argument.

First we will list possible timezones:

$ timedatectl list-timezones
Africa/Abidjan
Africa/Accra
Africa/Algiers
Africa/Bissau
Africa/Cairo
...

The list of possible time zones is long, so the use of the grep command is recommended in this case.

Next we can set the timezone using one of the elements of the list that was returned:

$ timedatectl set-timezone Africa/Cairo
$ timedatectl
               Local time: Thu 2019-12-05 18:18:10 EET
           Universal time: Thu 2019-12-05 16:18:10 UTC
                 RTC time: Thu 2019-12-05 16:18:10
                Time zone: Africa/Cairo (EET, +0200)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

Keep in mind that the name of the time zone must be exact. Africa/Cairo for example will change the time zone, but cairo or africa/cairo will not.

Disabling NTP Using timedatectl

In some cases it might be necessary to disable NTP. This could be done using systemctl but we will demonstrate this using timedatectl:

# timedatectl set-ntp no
$ timedatectl
             Local time: Thu 2019-12-05 18:19:04 EET Universal time: Thu 2019-12-05 16:19:04 UTC
               RTC time: Thu 2019-12-05 16:19:04
              Time zone: Africa/Cairo (EET, +0200)
            NTP enabled: no
       NTP synchronized: no
        RTC in local TZ: no
             DST active: n/a

Setting Time Zone Without timedatectl

Setting time zone information is a standard step when installing Linux on a new machine. If there is a graphical installation process, this will most likely be handled without any further user input.

The /usr/share/zoneinfo directory contains information for the different time zones that are possible. In the zoneinfo directory, there are subdirectories that contain the names of continents as well as other symbolic links. It is recommended to find your region’s zoneinfo starting from your continent.

zoneinfo files contain rules required to calculate the local time offset in relation to UTC, and they also are important if your region observes Daylight Savings Time. The contents of /etc/localtime will be read when Linux needs to determine the local time zone. In order to set the time zone without the use of a GUI, the user should create a symbolic link for their location from /usr/share/zoneinfo to /etc/localtime. For example:

$ ln -s /usr/share/zoneinfo/Canada/Eastern /etc/localtime

After setting the correct time zone, it is often recommended to run:

# hwclock --systohc

This will set the hardware clock from the system clock (that is, the real-time clock will be set to the same time as date). Please note that this command is run with root privileges, in this case by being logged in as root.

/etc/timezone is similar to /etc/localtime. It is a data representation of the local time zone, and as such it can be read using cat:

$ cat /etc/timezone
America/Toronto

Note that this file is not used by all Linux distributions.

Setting Date and Time Without timedatectl

Note

Most modern Linux systems use systemd for its configuration and services and as such it is not recommended that you use date or hwclock for setting time. systemd uses timedatectl for this. Nonetheless it is important to know these legacy commands in the event that you must administer an older system.

Using date

date has an option to set the system time. Use --set or -s to set the date and time. You may also choose to use --debug to verify the correct parsing of the command:

# date --set="11 Nov 2011 11:11:11"

Note that root privileges are required to set the date here. We may also choose to change to time or date independently:

# date +%Y%m%d -s "20111125"

Here we must specify the sequences so that our string is parsed properly. For example %Y refers to the year, and so the first four digits 2011 will be interpreted as the year 2011. Similarly, %T is the sequence for time, and it is demonstrated here by setting time:

# date +%T -s "13:11:00"

After changing system time, it is recommended to also set the hardware clock so that both system and hardware clocks are synchronised:

# hwclock --systohc

systohc means “system clock to hardware clock”.

Using hwclock

Rather than setting the system clock and updating the hardware clock, you may choose to reverse the process. We will start by setting the hardware clock:

# hwclock --set --date "4/12/2019 11:15:19"
# hwclock
Fri 12 Apr 2019 6:15:19 AM EST -0.562862 seconds

Notice that by default hwclock is expecting UTC time, but returns the local time by default.

After setting the hardware clock, we will need to update the system clock from it. hctosys can be understood to mean “hardware clock to system clock”.

# hwclock --hctosys

Guided Exercise

  1. Indicate whether the following commands are displaying or modifying system time or hardware time:

    Command(s) System Hardware Both

    date -u

    hwclock --set --date "12:00:00"

    timedatectl

    timedatectl | grep RTC

    hwclock --hctosys

    date +%T -s "08:00:00"

    timedatectl set-time 1980-01-10

  2. Observe the following output, and then correct the format of the argument so that the command is successful:

    $ date --debug --date "20/20/12 0:10 -3"
    
    date: warning: value 20 has less than 4 digits. Assuming MM/DD/YY[YY]
    date: parsed date part: (Y-M-D) 0002-20-20
    date: parsed time part: 00:10:00 UTC-03
    date: input timezone: parsed date/time string (-03)
    date: using specified time as starting value: '00:10:00'
    date: error: invalid date/time value:
    date:     user provided time: '(Y-M-D) 0002-20-20 00:10:00 TZ=-03'
    date:        normalized time: '(Y-M-D) 0003-08-20 00:10:00 TZ=-03'
    date:                                  ---- --
    date:      possible reasons:
    date:        numeric values overflow;
    date:        incorrect timezone
    date: invalid date ‘20/20/2 0:10 -3’
  3. Use the date command and sequences so that the system’s month is set to February. Leave the rest of the date and time unchanged.

  4. Assuming that the command above was successful, use hwclock to set the hardware clock from the system clock.

  5. There is a location called eucla. What continent is it part of? Use the grep command to find out.

  6. Set your current timezone to that of eucla.

Explorational Exercises

  1. Which method of setting time is optimal? In what scenario might the preferred method be impossible?

  2. Why do you think there are so many methods to accomplish the same thing, i.e. setting system time?

  3. After January 19, 2038, Linux System Time will require a 64-bit number to store. However, it is possible that we could simply choose to set a “New Epoch”. For example, January 1st, 2038 at midnight could be set to a New Epoch Time of 0. Why do you think this has not become the preferred solution?

Summary

In this lesson you learned:

  • How to display the time in different formats from the command line.

  • The difference between the system clock and the hardware clock in Linux.

  • How to manually set the system clock.

  • How to manually set the hardware clock.

  • How to change the system’s time zone.

Commands used in this lesson:

date

Display or the change the system clock. Other options:

-u

Display UTC time.

+%s

Use a sequence to display Epoch time.

--date=

Specify a specific time to display, as opposed to current time.

--debug

Display debug messages when parsing a user-inputted date.

-s

Set system clock manually.

hwclock

Display or change the hardware clock.

--systohc

Use system clock to set hardware clock.

--hctosys

Use hardware clock to set system clock.

--set --date

Set hardware clock manually.

timedatectl

Display system and hardware clocks, as well as NTP configuration on systemd-based Linux systems.

set-time

Set the time manually.

list-timezones

List possible timezones.

set-timezone

Set timzone manually.

set-ntp

Enable/disable NTP.

Answers to Guided Exercises

  1. Indicate whether the following commands are displaying or modifying system time or hardware time:

    Command(s) System Hardware Both

    date -u

    X

    hwclock --set --date "12:00:00"

    X

    timedatectl

    X

    timedatectl | grep RTC

    X

    hwclock --hctosys

    X

    date +%T -s "08:00:00"

    X

    timedatectl set-time 1980-01-10

    X

  2. Observe the following output, and then correct the format of the argument so that the command is successful:

    $ date --debug --date "20/20/12 0:10 -3"
    
    date: warning: value 20 has less than 4 digits. Assuming MM/DD/YY[YY]
    date: parsed date part: (Y-M-D) 0002-20-20
    date: parsed time part: 00:10:00 UTC-03
    date: input timezone: parsed date/time string (-03)
    date: using specified time as starting value: '00:10:00'
    date: error: invalid date/time value:
    date:     user provided time: '(Y-M-D) 0002-20-20 00:10:00 TZ=-03'
    date:        normalized time: '(Y-M-D) 0003-08-20 00:10:00 TZ=-03'
    date:                                  ---- --
    date:      possible reasons:
    date:        numeric values overflow;
    date:        incorrect timezone
    date: invalid date ‘20/20/2 0:10 -3’

    date --debug --set "12/20/20 0:10 -3"

  3. Use the date command and sequences so that the system’s month is set to February. Leave the rest of the date and time unchanged.

    date +%m -s "2"

  4. Assuming that the command above was successful, use hwclock to set the hardware clock from the system clock.

    hwclock -systohc

  5. There is a location called eucla. What continent is it part of? Use the grep command to find out. Enter the complete command below:

    timedatectl list-timezones \| grep -i eucla

    OR

    grep -ri eucla /usr/share/zoneinfo

  6. Set your current timezone to that of eucla.

    timedatectl set-timezone 'Australia/Eucla'

    or

    ln -s /usr/share/zoneinfo/Australia/Eucla /etc/localtime

Answers to Explorational Exercises

  1. Which method of setting time is optimal? In what scenario might the preferred method be impossible?

    In most Linux distributions, NTP is enabled by default and should be left to set system time without interference. However, if there is a Linux system that isn’t connected to the internet, NTP will be inaccessible. For example, an embedded Linux system running on industrial equipment might not have network connectivity.

  2. Why do you think there are so many methods to accomplish the same thing, i.e. setting system time?

    Since setting time has been a requirement of all *nix systems for decades, there are many legacy methods for setting time that are still maintained.

  3. After January 19, 2038, Linux System Time will require a 64-bit number to store. However, it is possible that we could simply choose to set a “New Epoch”. For example, January 1st, 2038 at midnight could be set to a New Epoch Time of 0. Why do you think this has not become the preferred solution?

    By 2038 the vast majority of computers will already be running 64-bit CPUs, and using a 64-bit number won’t degrade performance in any significant way. However, it would be impossible to estimate the risks of “resetting” Epoch time in such a way. There is a lot of legacy software that might be impacted. Banks and large businesses, for example, often have a large amount of older programs that they rely on for internal use. So this scenario, like so many others, is a study in trade-offs. Any 32-bit systems still running in 2038 would be impacted by an Epoch Time overflow, but legacy software would be impacted by changing the value of Epoch.

Linux Professional Insitute Inc. All rights reserved. Visit the Learning Materials website: https://learning.lpi.org
This work is licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.

Next Lesson

108.1 Maintain system time (108.1 Lesson 2)

Read next lesson

Linux Professional Insitute Inc. All rights reserved. Visit the Learning Materials website: https://learning.lpi.org
This work is licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.

LPI is a non-profit organization.

© 2022 Linux Professional Institute (LPI) is the global certification standard and career support organization for open source professionals. With more than 200,000 certification holders, it's the world’s first and largest vendor-neutral Linux and open source certification body. LPI has certified professionals in over 180 countries, delivers exams in multiple languages, and has hundreds of training partners.

Our purpose is to enable economic and creative opportunities for everybody by making open source knowledge and skills certification universally accessible.

  • LinkedIn
  • flogo-RGB-HEX-Blk-58 Facebook
  • Twitter
  • Contact Us
  • Privacy and Cookie Policy

Spot a mistake or want to help improve this page? Please let us know.

© 1999–2022 The Linux Professional Institute Inc. All rights reserved.