
If your Ubuntu server is logging events in the wrong time, firing cron jobs at odd hours, or showing SSL certificate errors out of nowhere, a misconfigured timezone is likely the culprit. Setting up timezone on Ubuntu 26.04 LTS is one of the first tasks you should complete on any fresh installation, whether you are running a production web server, a home lab, or a VPS hosted halfway across the world. This guide walks you through every method available, from the fastest one-liner in the terminal to the interactive graphical interface, so you can pick the approach that fits your workflow. You will also learn why each step matters, not just how to run it, because understanding the reasoning is what separates a confident sysadmin from someone who blindly copies commands.
A wrong timezone does not just display the wrong clock time. It breaks things silently. I have seen a misconfigured timezone cause a cron-based database backup job to fire during peak business hours instead of 2:00 AM, because the server was running UTC while the team expected local time. I have also debugged NTP sync failures that turned out to be timezone-related confusion between the hardware clock and the system clock. After more than ten years managing Ubuntu servers in production, I can tell you that timezone configuration is not a “set it and forget it” task. It requires verification at multiple layers. This guide gives you exactly that.
Prerequisites
Before you run any command in this guide, make sure your environment meets the following requirements:
- Operating System: Ubuntu 26.04 LTS (these commands also work on 22.04 and 24.04)
- User Privileges: A user account with
sudoaccess or the root user directly - Shell Access: SSH session or direct terminal on the machine
systemdactive: Ubuntu 26.04 usessystemdby default; confirm withsystemctl is-active systemd-timedated- Internet connectivity: Required only for NTP synchronization in Step 6; all timezone setting steps work offline
timedatectlavailable: Pre-installed on all Ubuntu releases usingsystemd; no extra packages needed
Step 1: Check Your Current Timezone
Before changing anything, always document what you have.
This rule applies in every sysadmin scenario. On a live server, you never want to modify a configuration without knowing its current state first. If something breaks after your change, you need to know exactly what to revert to.
Run this command:
timedatectl
You will see output similar to this:
Local time: Mon 2026-04-27 10:17:00 WIB
Universal time: Mon 2026-04-27 03:17:00 UTC
RTC time: Mon 2026-04-27 03:17:00
Time zone: Asia/Jakarta (WIB, +0700)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
Here is what each field tells you:
- Local time: The current time in your configured timezone
- Universal time: The current UTC time, which is the base reference for all timekeeping
- RTC time: The hardware clock time stored on your motherboard’s battery-backed chip
- Time zone: Your currently active IANA timezone identifier
- System clock synchronized: Whether
systemd-timesyncdhas confirmed NTP sync - NTP service: Whether the network time service is active
- RTC in local TZ: Should always read
noon a Linux server (explained in Step 6)
For a quick single-line check, you can also read the timezone file directly:
cat /etc/timezone
This file stores the plain text timezone name and is read by some applications that bypass systemd entirely.
Step 2: List All Available Timezones
You cannot guess an IANA timezone name. You have to look it up.
The IANA timezone database is the global standard for timezone definitions. It uses an Area/City format, such as America/New_York, Europe/Berlin, or Asia/Jakarta. Using a shorthand like WIB or EST will not work with timedatectl and will throw an error.
List all available timezones with this command:
timedatectl list-timezones
That output runs into hundreds of entries. Use grep to filter by region:
timedatectl list-timezones | grep -i asia
timedatectl list-timezones | grep -i america
timedatectl list-timezones | grep -i europe
To find a specific city:
timedatectl list-timezones | grep -i jakarta
timedatectl list-timezones | grep -i london
timedatectl list-timezones | grep -i chicago
Why the IANA Database Matters
The IANA database does not just map city names to UTC offsets. It also stores historical timezone changes, Daylight Saving Time (DST) transition rules, and leap second adjustments. When you set Asia/Jakarta, the system knows that Jakarta observes WIB (+07:00) year-round with no DST. When you set America/New_York, the system knows to shift between EST (-05:00) and EDT (-04:00) automatically on DST transition dates. This accuracy is critical for scheduling, log timestamps, and certificate validation.
Step 3: Set the Timezone Using timedatectl (Recommended Method)
This is the correct, modern method for Ubuntu 26.04 LTS.
sudo timedatectl set-timezone Asia/Jakarta
Replace Asia/Jakarta with the exact IANA string you identified in Step 2.
Verify the Change Immediately
timedatectl
date
The timedatectl output should now show your new timezone under Time zone:. The date command should display the correct local time with the right UTC offset.
Why This is the Recommended Method
When you run sudo timedatectl set-timezone, three things happen at once:
- The
/etc/localtimesymlink gets updated to point to the correct file inside/usr/share/zoneinfo/ - The
/etc/timezonefile gets updated with the plain text timezone name systemd-timedatedbroadcasts the change to all activesystemdunits via D-Bus, so running services pick up the new timezone without restarting
No reboot needed. No manual file editing. One command handles everything atomically. This is exactly why timedatectl is the preferred method on any systemd-based Linux server.
Why Not Use tzselect?
Some older guides suggest the tzselect command. Do not use it for permanent server configuration. tzselect only modifies the TZ environment variable in your current shell session. The moment you log out or open a new SSH connection, the system reverts to whatever is stored in /etc/timezone. It is useful for quick local testing, but it is not a system-wide change.
Step 4: Alternative Method Using dpkg-reconfigure
Use this method when you want a guided, interactive selection instead of typing an exact timezone string.
sudo dpkg-reconfigure tzdata
After running this command, an ncurses menu appears in your terminal. It works in two steps:
- Select your geographic area (e.g., Asia, America, Europe, Pacific)
- Select your specific city or region (e.g., Jakarta, London, Chicago)
Press Enter to confirm each selection. The command updates both /etc/timezone and /etc/localtime automatically.
Why This Method Exists
dpkg-reconfigure tzdata is the Debian package-level configuration tool. It updates timezone settings at the package management layer, which matters for two scenarios:
- Automated provisioning: You can drive this menu non-interactively using
debconf-set-selectionsin scripts or Ansible playbooks - Container environments: On minimal Ubuntu Docker images where
systemd-timedatedis not running,dpkg-reconfigureis the only reliable way to set the timezone
For normal server use, timedatectl from Step 3 is faster. But knowing dpkg-reconfigure gives you a fallback when timedatectl is unavailable or disabled.
Step 5: Set the Timezone via GNOME GUI (Desktop Users Only)
If you are running Ubuntu 26.04 Desktop with GNOME, you can set the timezone through the graphical settings panel.
Follow these steps:
- Click Activities in the top-left corner
- Open Settings
- Navigate to System > Date & Time
- Toggle Automatic Time Zone to OFF
- Click the Time Zone button
- Type your city name in the search box
- Select the matching result and close the window
Why Turn Off Automatic Time Zone First
If you leave Automatic Time Zone enabled, the system uses location services and IP geolocation to detect your timezone. On a VPS, this almost always picks the datacenter’s timezone, not yours. A server hosted in Frankfurt will default to Europe/Berlin even if you want Asia/Jakarta. Disabling automatic detection before making your selection prevents the system from overwriting your choice silently.
Note for Server Users
Ubuntu Server has no GNOME interface. If you are on a headless server, skip this step and use timedatectl from Step 3. The CLI method is faster anyway.
Step 6: Enable NTP Time Synchronization
Setting the timezone and ensuring accurate time are two separate tasks. You need both.
Think of it this way: the timezone tells the system which offset from UTC you are in. NTP ensures that the UTC base clock is actually correct. If your UTC clock is off by 20 minutes, your local time will be wrong by 20 minutes even after you set the right timezone.
Enable NTP synchronization with:
sudo timedatectl set-ntp true
Verify that sync is active:
timedatectl show --property=NTPSynchronized
timedatectl
You should see:
System clock synchronized: yes
NTP service: active
Why systemd-timesyncd and Not ntpd
Ubuntu 26.04 ships with systemd-timesyncd as its default NTP client. It is lightweight, well-integrated with systemd, and perfectly adequate for any server that is consuming time (not serving it to other machines). If you run a network that needs a dedicated NTP source for dozens of hosts, chrony or ntpd is a better choice. For everything else, timesyncd covers the job.
Why RTC in Local TZ Must Stay No
Your server’s Real Time Clock (RTC) is the hardware clock on the motherboard. It should always store time in UTC, not local time. The field RTC in local TZ: no in the timedatectl output confirms this.
If this field shows yes, the system stores local time in the RTC. During a DST transition, the clock will jump forward or back by one hour at the hardware level. This can cause duplicate log entries, missed cron jobs, and confusing system behavior. To force RTC back to UTC:
sudo timedatectl set-local-rtc 0
Step 7: Verify the Complete Timezone Configuration
Never assume a change worked. Verify it from four independent sources.
Run all four commands and compare the output:
timedatectl
date
cat /etc/timezone
ls -la /etc/localtime
What to Check in Each Output
timedatectl reads timezone data from the D-Bus interface of systemd-timedated. It shows the authoritative system-level configuration.
date reads time directly from the kernel. The offset shown (e.g., +0700) must match your chosen timezone.
cat /etc/timezone reads the package-level plain text file. Some applications, including certain Python frameworks and older Java runtimes, read this file directly without going through systemd. It must match.
ls -la /etc/localtime shows the symlink target. You should see something like:
lrwxrwxrwx 1 root root 33 Apr 27 10:17 /etc/localtime -> /usr/share/zoneinfo/Asia/Jakarta
If any of these four outputs disagree, you have a partial configuration. The most common cause is a manually edited /etc/localtime symlink that was not accompanied by an update to /etc/timezone. Fix it by re-running sudo timedatectl set-timezone [your timezone] to sync all layers at once.
Step 8: Automate Timezone Setup for Multiple Servers
If you manage more than one Ubuntu 26.04 server, you should never set timezones manually one by one.
Every fresh Ubuntu VPS on providers like DigitalOcean, Hetzner, or Vultr defaults to UTC. That is usually fine for purely international workloads. But if you need a specific local timezone across a fleet, a simple script handles it consistently:
#!/bin/bash
# Set timezone and enable NTP on Ubuntu 26.04 LTS
TARGET_TZ="Asia/Jakarta"
sudo timedatectl set-timezone "$TARGET_TZ"
sudo timedatectl set-ntp true
echo "Timezone set to:"
timedatectl | grep "Time zone"
echo "NTP status:"
timedatectl | grep "NTP service"
Save this as set_timezone.sh, make it executable with chmod +x set_timezone.sh, and run it as part of your server provisioning process.
Why Include set-ntp true in the Script
Many sysadmins set the timezone but forget to confirm NTP is active. On some cloud providers, NTP is enabled by default but can be accidentally disabled during other configuration steps. Including it in the script ensures both timezone and time accuracy are handled in one pass. It is a small addition that prevents a class of bugs that are surprisingly painful to diagnose later.
Troubleshooting Common Timezone Errors
Error 1: Failed to set time zone: Access denied
Why it happens: You ran timedatectl set-timezone without sudo. The systemd-timedated service requires elevated D-Bus privileges to modify system timezone settings.
Fix:
sudo timedatectl set-timezone Asia/Jakarta
Always prefix timezone change commands with sudo.
Error 2: Failed to set time zone: Invalid time zone ‘Jakarta’
Why it happens: You used a city name or abbreviation without the IANA region prefix. The correct format is always Area/City.
Fix: Find the exact string first:
timedatectl list-timezones | grep -i jakarta
Then use the exact result:
sudo timedatectl set-timezone Asia/Jakarta
Error 3: System clock synchronized: no After Enabling NTP
Why it happens: systemd-timesyncd cannot reach the NTP pool servers. The most common cause is a firewall rule blocking outbound UDP port 123.
Fix:
cat /etc/systemd/timesyncd.conf
Check the NTP= and FallbackNTP= lines. If they are commented out, add explicit servers:
sudo nano /etc/systemd/timesyncd.conf
Set the following:
[Time]
NTP=0.ubuntu.pool.ntp.org 1.ubuntu.pool.ntp.org
FallbackNTP=ntp.ubuntu.com
Then restart the service:
sudo systemctl restart systemd-timesyncd
timedatectl show --property=NTPSynchronized
Error 4: Clock Shows Wrong Time Even After Setting Correct Timezone
Why it happens: The timezone is correct, but the hardware clock (RTC) stored a wrong base time before NTP sync happened. The system clock derives from the RTC at boot.
Fix: Force an immediate NTP sync and write it to the RTC:
sudo systemctl restart systemd-timesyncd
sudo hwclock --systohc
timedatectl
Error 5: Cron Jobs Still Fire at Wrong Times After Timezone Change
Why it happens: cron and systemd timers that were already running cached the old timezone. They do not always pick up changes made to a live system without a nudge.
Fix: Restart the cron daemon and list active timers to verify:
sudo systemctl restart cron
sudo systemctl list-timers
Confirm the NEXT column shows the expected local time for each scheduled job.