Skip to content

Time Zone and Locale Settings

Regardless of where a server physically sits, its system clock and text/date formatting need to be set correctly — the wrong time zone confuses log analysis, and the wrong locale makes dates, numbers, or currency show up in unexpected formats in command output. systemd manages both through one family of tools: timedatectl and localectl.

This article continues the systemd tool family covered in init and systemd.

What You Will Learn

By the end of this article you will be able to:

  • check and change the current time zone and clock state with timedatectl;
  • explain why production servers usually stay on UTC;
  • view and change the system locale with localectl;
  • explain the difference between LANG, LC_* variables, and the system locale setting;
  • recognize typical problems caused by an incorrect time zone or locale.

timedatectl: Time and Time Zone

Viewing the current state:

timedatectl
               Local time: Fri 2026-07-24 10:00:00 UTC
           Universal time: Fri 2026-07-24 10:00:00 UTC
                 RTC time: Fri 2026-07-24 10:00:00
                Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

Key fields:

  • Time zone — the currently configured time zone;
  • System clock synchronized — whether the system clock matches an NTP time server;
  • NTP service — whether the time-synchronization service is active.

Viewing Available Time Zones

timedatectl list-timezones | grep -i tashkent
Asia/Tashkent

Changing the Time Zone

sudo timedatectl set-timezone Asia/Tashkent
timedatectl | grep 'Time zone'
               Time zone: Asia/Tashkent (+05, +0500)

Info

Production servers usually keep their time zone set to UTC, rather than the real geographic zone. The reason: when comparing logs collected from multiple servers, working with cron schedules, or doing any time-based calculation, having every machine anchored to the same fixed reference point (UTC) makes analysis considerably simpler. Time-zone-specific display is typically handled in the application or presentation layer, not at the system level.

Managing NTP Synchronization

sudo timedatectl set-ntp true
timedatectl | grep -E 'synchronized|NTP service'

set-ntp true/false turns automatic synchronization with a network time server on or off. When disabled, the clock relies purely on the hardware clock (RTC) and can gradually drift away from the actual time.

Warning

System clock synchronized: no is worth paying attention to: TLS certificate validation, cron scheduling, log ordering, and many distributed systems (such as Kerberos authentication) are all sensitive to incorrect time. If you see this state, check first whether the NTP service (typically systemd-timesyncd or chronyd) is actually running.

Setting the Clock Manually, and the RTC Time Zone

Setting the time by hand only makes sense when NTP is off — with synchronization active, systemd refuses the change rather than let a manual value fight the time server:

sudo timedatectl set-time "2026-07-24 10:00:00"
Failed to set time: Automatic time synchronization is enabled

The fix is to set-ntp false first — but on a server the better answer is usually to leave NTP on and fix synchronization instead of overriding it. One related field trips people up on dual-boot machines: RTC in local TZ. Linux keeps the hardware clock (RTC) in UTC by default, while Windows keeps it in local time, so a dual-boot machine shows the wrong time in one OS until sudo timedatectl set-local-rtc 1 is run. On a server, always leave the RTC in UTC — set-local-rtc 1 is documented as an unreliable, discouraged mode.

localectl: System Locale Settings

Viewing the current state:

localectl status
   System Locale: LANG=en_US.UTF-8
       VC Keymap: us
      X11 Layout: us

A locale is a set of settings defining a system's language, date format, number separators, and currency display rules. LANG=en_US.UTF-8 means English, US formatting conventions, UTF-8 encoding.

Viewing Available Locales

locale -a | grep -i utf8 | head -n 5

If the locale you need isn't listed, it must be generated first:

sudo locale-gen en_US.UTF-8

Changing the System Locale

sudo localectl set-locale LANG=en_US.UTF-8
localectl status

LANG/LC_* and the Current Shell Environment

localectl sets the system-wide default, but any user or shell session can override it with its own environment variable:

echo "$LANG"
LC_ALL=C date
  • LANG — the default locale, applied to any LC_* variable that isn't set explicitly;
  • LC_TIME, LC_NUMERIC, LC_MONETARY, and others — a separate locale for a specific category;
  • LC_ALL — temporarily overrides every LC_* setting, taking priority over all of them.
date
LC_TIME=en_GB.UTF-8 date

These two commands show the same moment in time, but — if the matching locale is installed — in a different format.

Info

When writing a script that needs to parse a date or number format predictably, it's recommended to run it with LC_ALL=C or LC_ALL=C.UTF-8 — this keeps command output in a stable, predictable format regardless of the user's or environment's locale setting.

Common Mistakes

Leaving Every Server in a Different Time Zone

In a multi-server environment, if each machine runs in its own geographic time zone, merging logs and reconstructing the sequence of events becomes much harder. Keeping every server on UTC eliminates this problem upfront.

Concluding "the Time Is Wrong" Without Checking NTP

In many cases, the problem isn't the time zone at all, but NTP synchronization being disabled or broken. Check the System clock synchronized value in timedatectl first.

Trying to Use a Locale That Was Never Generated

localectl set-locale may not give an explicit error if a locale doesn't exist; an unexpected fallback to C or POSIX formatting in command output can be the actual symptom. Check with locale -a first, and generate it with locale-gen if needed.

Exercises

  1. Read every field in timedatectl output and explain each one in your own words.
  2. In a test VM, change the time zone to Asia/Tashkent, then compare the output of date and timedatectl.
  3. Compare the output of LC_ALL=C date and a plain date — explain the difference.
  4. Compare localectl status with echo $LANG and explain when the system-level and shell-level settings can differ.

Verification criterion: you should be able to explain, for a server showing unexpected date formatting in a script's output, which two settings (locale, or LC_ALL override) to check first.

Summary

timedatectl manages the time zone, current time, and NTP synchronization state, while localectl manages language- and format-related locale settings. Production servers typically stay on UTC, and scripts typically use LC_ALL=C for stable formatting — both practices prevent unexpected discrepancies in a multi-server, automated environment.

References