On Linux, I need to find the currently configured timezone as an Olson location. I want my (C or C++) code to be portable to as many Linux systems as possible.
For e
The libc accesses the Olson database when tzset is called, and uses simplified time zones afterwards. tzset
looks at the TZ
environment variable first, and falls back to parsing the binary data in /etc/localtime
.
At first systemd standardised on having the Olson time zone name in /etc/timezone
, Debian-style. After systemd 190 and the /usr merge, systemd only reads and updates /etc/localtime
, with the extra requirement that the file be a symlink to /usr/share/zoneinfo/${OLSON_NAME}
.
Looking at TZ
, then readlink("/etc/localtime")
, is the most reliable way to match the libc's tzset
logic and still keep symbolic Olson names. For systems that don't follow the systemd symlink convention, reading /etc/timezone
(and possibly checking that /usr/share/zoneinfo/$( is the same as
/etc/localtime
) is a good fallback.
If you can live without symbolic names, parsing the /etc/localtime
tzfile is as portable as it gets, though a lot more complex. Reading just the last field gets you a Posix time zone (for example: CST5CDT,M3.2.0/0,M11.1.0/1
), which can interoperate with a few time-handling libraries, but drops some of the metadata (no historical transition info).