Guides

Linux date and timezone: date formats, timedatectl and setting the clock

Set the date in Linux, format it (+%F %T, +%s, ISO 8601) and convert with date -d; change the timezone with timedatectl, plus NTP and why servers use UTC.

Published ~8 min read
On this page

Short answer: date prints the current date and time, and date '+%F %T' formats it as 2026-10-22 14:05:09. To change the timezone, run sudo timedatectl set-timezone Europe/Berlin. To set the clock by hand, first stop network time with sudo timedatectl set-ntp false, then run sudo timedatectl set-time '2026-10-22 14:05:00'.

the short version
date                                   # Thu Oct 22 14:05:09 UTC 2026
date '+%F %T'                          # 2026-10-22 14:05:09
date -Iseconds                         # 2026-10-22T14:05:09+00:00
timedatectl                            # timezone, NTP and clock status
timedatectl list-timezones | grep -i berlin
sudo timedatectl set-timezone Europe/Berlin

Every date output on this page was produced with GNU coreutils 9.1 on Debian 12 on 21 October 2026, with a fixed input time so the results are reproducible. timedatectl status was read on the same machine (systemd 252). Nothing was changed there, so set-time, set-timezone, set-ntp, hwclock and chrony are written from their man pages. Ubuntu, Rocky Linux and AlmaLinux use the same date and timedatectl.

date format strings: cheat sheet

A format starts with + and is best quoted. All outputs below are for 2026-10-22 14:05:09 in UTC:

FormatOutputMeaning
+%F2026-10-22ISO date, same as %Y-%m-%d
+%T14:05:09Time, same as %H:%M:%S
+'%F %T'2026-10-22 14:05:09The usual log format
+%s1792677909Unix time: seconds since 1970-01-01 UTC
+%s%3N1792677909000Milliseconds (%N is nanoseconds)
+%Y%m%d20261022Compact date for file names
+%Y-%m-%d_%H-%M-%S2026-10-22_14-05-09Sortable file name with time
+%z / +%:z+0000 / +00:00Offset from UTC
+%ZUTCZone abbreviation (CEST, EDT and so on)
+'%A, %d %B %Y'Thursday, 22 October 2026Names of day and month
+%a / +%bThu / OctShort names
+%-d.%-m.%Y22.10.2026No leading zeros (GNU extension)
+%j295Day of the year
+%V43ISO week number
+%u4Day of the week, Monday = 1
date in scripts
tar czf "etc-$(date +%F).tar.gz" /etc          # etc-2026-10-22.tar.gz
echo "$(date '+%F %T') backup done" >> /var/log/backup.log
start=$(date +%s); sleep 1; echo "took $(( $(date +%s) - start ))s"

ISO 8601 and RFC formats: -I, -R, --rfc-3339

with TZ=Europe/Berlin, local time 2026-10-22 14:05:09
date -I                  # 2026-10-22
date -Iminutes           # 2026-10-22T14:05+02:00
date -Iseconds           # 2026-10-22T14:05:09+02:00
date -Ins                # 2026-10-22T14:05:09,000000000+02:00
date -u -Iseconds        # 2026-10-22T12:05:09+00:00
date -R                  # Thu, 22 Oct 2026 14:05:09 +0200   (RFC 5322, mail headers)
date --rfc-3339=seconds  # 2026-10-22 14:05:09+02:00

Use -Iseconds for anything a machine or a colleague in another country will read: it is unambiguous and carries its offset. Note the comma before the nanoseconds in -Ins, which some parsers do not accept; -u prints UTC regardless of the system zone.

date -d: relative dates and epoch conversions

date -d (GNU date)
date -d @1792677909                 # epoch to date: Thu Oct 22 14:05:09 UTC 2026
date -d '2026-10-22' +%s            # date to epoch: 1792627200
date -d yesterday +%F               # yesterday's date
date -d 'tomorrow 03:00' '+%F %T'
date -d '2026-10-22 +3 days' +%F    # 2026-10-25
date -d '3 days ago' +%F
date -d '2026-11-01 -1 day' +%F     # 2026-10-31: last day of a month
date -r /etc/hostname '+%F %T'      # a file's modification time
echo $(( ($(date -d 2026-12-25 +%s) - $(date -d 2026-10-22 +%s)) / 86400 ))   # 64 days

To convert a time from another zone, put the zone inside the string: date -d 'TZ="Europe/Berlin" 2026-10-22 09:00' printed 07:00:00 UTC on a UTC machine, and with TZ=Asia/Tokyo in front, 16:00:00 JST. date -d is GNU only: on macOS and BSD the equivalent is date -j -f or date -v.

Three traps in date -d

  • A number after a time becomes a timezone. date -d '2026-10-22 14:05:09 +3 days' returned 2026-10-23 11:05:09, not the 25th: +3 was read as UTC+3 and the bare “days” as one day. --debug shows it (parsed time part: 14:05:09 UTC+03). Put the zone in explicitly ('2026-10-22 14:05:09 UTC +3 days') or drop the plus sign ('… 14:05:09 3 days'); both give the 25th.
  • Months overflow. date -d '2026-01-31 +1 month' gives 2026-03-03, because February 31 does not exist and the extra days roll over. Do month arithmetic from the first of the month.
  • Natural language has limits. 'last day of month' is rejected with date: invalid date, as are impossible dates such as 2026-02-30. For the end of the current month, use date -d "$(date +%Y-%m-01) +1 month -1 day" +%F.

timedatectl: the clock, the zone and NTP

timedatectl status (read on Debian 12)
               Local time: Wed 2026-10-21 22:55:53 UTC
           Universal time: Wed 2026-10-21 22:55:53 UTC
                 RTC time: Wed 2026-10-21 22:55:52
                Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no
  • Time zone: the system zone, which is the target of the /etc/localtime symlink (/usr/share/zoneinfo/Etc/UTC here).
  • System clock synchronized: yes once the time service has reached a server and adjusted the clock.
  • NTP service: whether a time sync service is enabled; this is what set-ntp switches.
  • RTC time and RTC in local TZ: the hardware clock, kept in UTC as it should be. More in hwclock.

How do I change the timezone?

  1. 1Find the zone name
    list zones
    timedatectl list-timezones | grep -i -E 'berlin|amsterdam|new_york'

    Zone names are Region/City, such as Europe/Amsterdam or America/New_York. Prefer them to legacy names such as CET or EST5EDT: a Region/City zone carries that place’s full history of offsets and daylight saving rules.

  2. 2Set it
    set the zone
    sudo timedatectl set-timezone Europe/Berlin
    timedatectl | grep 'Time zone'      # Time zone: Europe/Berlin (CEST, +0200)

    This relinks /etc/localtime. Without systemd, do the same by hand with sudo ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime, or run sudo dpkg-reconfigure tzdata on Debian and Ubuntu.

  3. 3Restart what caches the zone

    Many long-running programs read the zone only when they start. Restart cron (on Rocky and AlmaLinux: crond), your database and your application services with systemctl, or reboot. A cron job that suddenly runs at the wrong hour is usually this step missing; see cron job not running.

One command or one user in another zone: TZ

TZ
TZ=America/New_York date            # Thu Oct 22 10:05:09 EDT 2026, for this command only
TZ=Asia/Kolkata date '+%F %T %:z'    # 2026-10-22 19:35:09 +05:30
export TZ=Europe/Amsterdam           # for this shell; put it in ~/.bashrc to keep it

TZ changes what you see, never the system clock. Spell it exactly: an unknown name does not raise an error. TZ=Mars/Olympus date printed UTC time with the abbreviation Mars, so a typo silently gives you UTC.

How do I set the date and time by hand?

set the clock manually
sudo timedatectl set-ntp false                     # stop automatic sync first
sudo timedatectl set-time '2026-10-22 14:05:00'    # date and time
sudo timedatectl set-time '14:05:00'               # time only
sudo timedatectl set-ntp true                      # switch sync back on afterwards

With network time active, set-time refuses with Failed to set time: Automatic time synchronization is enabled. The older sudo date -s '2026-10-22 14:05:00' is not blocked, but the sync service corrects the clock again at its next poll. On a server there is rarely a reason to set the clock by hand: if the time is wrong, fix synchronisation instead. To test how software behaves on another date, such as a certificate or licence expiry, run just that program under a fake clock (faketime '2027-01-01 00:00:00' date, from the faketime package) and leave the system clock alone.

systemd-timesyncd or chrony?

systemd-timesyncdchrony
What it isSimple SNTP client built into systemdFull NTP client and server
Usually found onDebian (it ran on the Debian 12 test machine); Ubuntu up to 24.04 LTSRocky Linux, AlmaLinux; new Ubuntu 26.04 LTS installs
Statustimedatectl timesync-statuschronyc tracking
Config file/etc/systemd/timesyncd.conf/etc/chrony/chrony.conf (Rocky, AlmaLinux: /etc/chrony.conf)
Can serve time to othersNoYes

Ubuntu 26.04 LTS made chrony the default for new installations, using Ubuntu’s time servers with NTS by default, according to its release notes. For one server that only needs correct time, timesyncd is enough. Pick chrony when the machine should serve time to others, when you want NTS, or when it must converge quickly after boot. On Debian and Ubuntu, installing chrony replaces systemd-timesyncd, and chronyc sources -v lists the servers it uses.

If System clock synchronized stays at no, check the service with systemctl status systemd-timesyncd (or chrony, chronyd on Rocky and AlmaLinux) and its log with journalctl, and make sure outgoing UDP port 123 is not blocked by a firewall.

The hardware clock: hwclock

hwclock (root)
sudo hwclock --show       # read the RTC; printed in local time
sudo hwclock --systohc    # write the system time to the RTC
sudo hwclock --hctosys    # set the system time from the RTC

The real-time clock keeps time while the machine is off; the kernel reads it at boot and NTP takes over from there. Keep it in UTC: the timedatectl man page warns that a local-time RTC “will create various problems with time zone changes and daylight saving adjustments”. On a VPS the RTC is virtual and supplied by the hypervisor, and the guest keeps time with a paravirtual clock (kvm-clock under KVM, visible in /sys/devices/system/clocksource/clocksource0/current_clocksource), so there is nothing to set.

Why servers should usually run on UTC

  • No daylight saving gaps. In Europe/Amsterdam, 2026-03-29 02:30 does not exist (date calls it an invalid date) and 2026-10-25 02:30 happens twice; date silently picked the CET one. A job or a log line in that hour is either skipped, doubled or ambiguous. UTC has no such hour.
  • Logs line up. Servers in Amsterdam, Frankfurt and a laptop in another zone produce comparable timestamps without mental arithmetic.
  • Applications expect it. Databases and most frameworks store UTC and convert for display; a server zone that differs adds a conversion step that can go wrong.

Many VPS images start on UTC (the test machine did too). If you prefer local time, for example so that cron schedules read naturally, that works too, as long as every log line carries its offset: date -Iseconds in your own scripts, journalctl -o short-iso or --utc when reading the journal (see output formats), and $time_iso8601 in an nginx log format. Setting the zone is one of the first steps in our initial server setup; whichever you choose, choose it once for all your servers.

Frequently asked

How do I change the timezone in Linux?

Run 'sudo timedatectl set-timezone Europe/Berlin', using a Region/City name from 'timedatectl list-timezones'. It relinks /etc/localtime. Restart cron and other long-running services afterwards, because many of them read the zone only when they start.

How do I set the date and time manually in Linux?

Turn network time off first with 'sudo timedatectl set-ntp false', then run 'sudo timedatectl set-time "2026-10-22 14:05:00"' with the date and time in quotes. With NTP on, timedatectl refuses with 'Automatic time synchronization is enabled'. Switch it back on with 'sudo timedatectl set-ntp true' when you are done.

How do I format the date as YYYY-MM-DD in Linux?

date +%F prints 2026-10-22, and date '+%F %T' adds the time as 14:05:09. For file names use date +%Y-%m-%d_%H-%M-%S, for Unix time date +%s, and for ISO 8601 with the UTC offset date -Iseconds.

Should a Linux server use UTC or local time?

UTC, as a rule. It has no daylight saving gaps or repeated hours, logs from servers in different zones line up, and applications store UTC anyway. Local time works too if every log line carries its offset, for example with date -Iseconds or journalctl -o short-iso.

Related articles

All guides