As title said, I'm looking for a simple way to get the canonical name of a timezone when providing a timezone name.
For example Asia/Calcutta
is the backward liked name of Asia/Kolkata
.
I'd expect ZoneInfo("Asia/Calcutta").key
to be Asia/Kolkata
, but it's not the case and ZoneInfo doesn't have any apparent way to follow link of get the canonical name.
Is there any way to get this information? Either in ZoneInfo or directly in tzdata?
Finally found an answer, turns out there's a file tzdata/zoneinfo/tzdata.zi
that contains amongst other things the data I needed.
Links are formated this way L CANONICAL_NAME BACKWARD_NAME
so I just parse the file to get the associations I need. I made a child class of ZoneInfo
for it as it was the most convenient for my usage:
import importlib.resources
from zoneinfo import ZoneInfo
class ZoneInfoCanonical(ZoneInfo):
__backward = {}
@property
def canonical(self) -> str:
"""
:return: Canonical name of the timezone it one exist, or timezone name.
"""
return self.backward_dict().get(self.key, self.key)
@classmethod
def backward_dict(cls) -> dict:
"""
Build a list of backward timezones names with link to the canonical name.
Store the list in class to avoid rebuilding it every time.
:return: Dict with key(backward name) and value(canonical name).
"""
# Load backward dict from tzdata files
if not cls.__backward:
# Path to the tzdata's backward file
backward_file = importlib.resources.files("tzdata") / "zoneinfo" / "tzdata.zi"
with backward_file.open("r") as file:
for line in file:
if line.startswith("L "):
canonical, backward = line.split()[1:3]
cls.__backward[backward] = canonical
return cls.__backward