Create TZ string from Python ZoneInfo

70 views Asked by At

I can easily get a ZoneInfo object for the time zone of my choice:

import zoneinfo
ct = zoneinfo.ZoneInfo('America/Chicago')

I need to create a TZ environment variable for an embedded system that doesn't have a timezone database, so I can't simply reuse the location string as you might do on a regular Linux system. I need to embed the actual daylight savings transition rules in the string, for my example it would look like:

TZ=CST06CDT05,M3.2.0/2,M11.1.0/2

I haven't been able to find any way to build that string. It doesn't bother me that the string might become obsolete if the rules change.

This also needs to work for time zones outside the U.S.

If there's a better way to get the information than using ZoneInfo, I'm willing to entertain answers for that too.

1

There are 1 answers

2
FObersteiner On

POSIX TZ strings can be found at the end of IANA time zone database files (version 2 or higher), see RFC 8536, sect. TZif footer. They are newline-separated from the rest, so you can obtain them for instance like

from pathlib import Path
import zoneinfo

zones = zoneinfo.available_timezones()

# path to IANA tz db on your system, adjust if needed
basepath = Path("/usr/share/zoneinfo/")

for z in zones:
    with open(basepath / z, "rb") as fobj:
        content = fobj.readlines()
    print(z, content[-1].decode("ASCII").strip("\n"))

which gives for example

...
Australia/North ACST-9:30
Europe/Gibraltar CET-1CEST,M3.5.0,M10.5.0/3
America/Bogota <-05>5
America/Los_Angeles PST8PDT,M3.2.0,M11.1.0
Asia/Ujung_Pandang WITA-8

Note that this only works "out of the box" on systems that ship with the IANA db (Mac, Linux). If you're on Windows, you'll first have to obtain the IANA database. You should be able to use the database version provided by the tzdata package. The database itself lives in [Python-version]\\Lib\\site-packages\\tzdata\\zoneinfo. The code to obtain the POSIX strings could then look something like

basepath = Path("C:\\Users\\username\\[path-to-Python]\\[Python-version]\\Lib\\site-packages\\tzdata\\zoneinfo")
zoneinfo.reset_tzpath(to=(basepath,))
zones = zoneinfo.available_timezones()

# now iterate zones as shown in the first snippet.

Alternatively, you can build the db yourself, Paul Eggert's tz repo has instructions on how to do so. You'll need make and a C-compiler for the utilities.