Playing with time zones
Nicolas B February 07, 2026 #RHEL #Linux #time zonesA few days ago, I was asked if the system of a customer would reflect a time change. More exactly, whether the Linux servers would reflect the time change in Morocco, as it changes every year during Ramadan. Although I know that the daylight saving time is correctly applied in France, as it is quite predictive (we apply DST time from the first sunday of March, until the latest sunday of October), I had no clue for Morocco, and I needed to know more. But before answering this question, let’s review how Linux systems keep their time accurate, and how they display it for human beings!
Network Time Protocol
NTP is the most popular protocol to synchronize systems’ clocks. According to RFC 1305
NTP timestamps are represented as a 64-bit unsigned fixed-point number, in seconds relative to 0h on 1 January 1900.
The NTP client converts this NTP timestamp and some metadata like leap seconds in a time usable by the system. The NTP client disciplines the system clock so that it stays close to UTC. On Linux, the system clock is represented as seconds since the Unix epoch (1970), without any notion of time zone. Every time the current date will be displayed, a conversion from this clock to the local time zone will be calculated.
Setting the time zone
On RHEL 8 through RHEL 10, the timedatectl tool is used to configure the system time zone.
All available time zones can be listed with: timedatectl list-timezones You can filter the output using grep:
# timedatectl list-timezones | grep Europe
[...]
Europe/Oslo
Europe/Paris
Europe/Podgorica
Europe/Prague
Europe/Riga
[...]
it is possible to see the current time zone configured using the same tool
# timedatectl
Local time: Sat 2026-02-07 15:15:10 CET
Universal time: Sat 2026-02-07 14:15:10 UTC
RTC time: Sat 2026-02-07 16:04:04
Time zone: Europe/Paris (CET, +0100)
System clock synchronized: yes
NTP service: active
RTC in local TZ: yes
When setting the time zone, timedatectl updates the /etc/localtime symbolic link to a file that contains the “rules” to compute local time depending on the date:
# ls -l /etc/localtime
lrwxrwxrwx. 1 root root 35 Jul 21 2021 /etc/localtime -> ../usr/share/zoneinfo/Europe/Prague
The time zone rules
Each time zone has a database that contains the rules to determine the current time, but the past or future ones.
This database is maintained by the IANA, and packaged in RHEL with the name tzdata.
It is recommended to update this database frequently using dnf update tzdata.
Each time this database is updated, a message is published in the tz-announce mailing list.
You can find a changelog in the tzdata package:
rpm -q --changelog tzdata
* Mon Mar 24 2025 Patsy Griffin <patsy@redhat.com> - 2025b-1
- Update to tzdata-2025b (RHEL-84748)
- Chile's Ays<C3><A9>n Region moves from -04/-03
to -03 year-round, diverging from America/Santiago and
creating a new zone America/Coyhaique.
* Tue Jan 21 2025 Patsy Griffin <patsy@redhat.com> - 2025a-1
Update to tzdata-2025a (RHEL-74309)
- Paraguay is now permanently at -03. This impacts timestamps
starting on 2025-03-22.
- Includes improvements to pre-1991 data for the Philippines.
- Etc/Unknown is now reserved.
Unfortunately, I couldn’t determine whether the rules for Morocco were updated for this year… but there is no better place to find out whether something exists than looking directly at it!
The tzdata files
zdump is a time zone dumper.
This tool can show every time change known in the tzdata for a specific time zone:
As Morocco’s time zone is Africa/Casablanca, let’s display all the time modifications for the 2020s:
zdump -i Africa/Casablanca | grep -E "202."
2020-04-19 02 +00
2020-05-31 03 +01 1
2021-04-11 02 +00
2021-05-16 03 +01 1
2022-03-27 02 +00
2022-05-08 03 +01 1
2023-03-19 02 +00
2023-04-30 03 +01 1
2024-03-10 02 +00
2024-04-14 03 +01 1
2025-02-23 02 +00
2025-04-06 03 +01 1
2026-02-15 02 +00
2026-03-22 03 +01 1
2027-02-07 02 +00
2027-03-14 03 +01 1
2028-01-23 02 +00
2028-03-05 03 +01 1
2029-01-14 02 +00
2029-02-18 03 +01 1
2029-12-30 02 +00
We can confirm that the system will reflect properly the time change this year, and there are rules until 2087!
Of course, the database will be updated if any change will occur in the future
Bonus, using the data command
Did you know that you could display any arbitrary date? By setting the time zone in the TZ environment variable, it can reflect how this date will be calculated:
TZ=Africa/Casablanca date -d '2026-02-14 12:00'
Sat Feb 14 12:00:00 +01 2026
TZ=Africa/Casablanca date -d '2026-02-15 12:00'
Sun Feb 15 12:00:00 +00 2026
In this exemple, we can observe that the time zone is UTC+1 on feb-14, and UTC on feb-15