Get the Olson TZ name for the local timezone?

datetime, linux, localtime, python, timezone

Solution

I think best bet is to go thru all pytz timezones and check which one matches local timezone, each pytz timezone object contains info about utcoffset and tzname like CDT, EST, same info about local time can be obtained from `time.timezone/altzone` and `time.tzname`, and I think that is enough to correctly match local timezone in pytz database e.g.

import time
import pytz
import datetime

local_names = []
if time.daylight:
    local_offset = time.altzone
    localtz = time.tzname[1]
else:
    local_offset = time.timezone
    localtz = time.tzname[0]

local_offset = datetime.timedelta(seconds=-local_offset)

for name in pytz.all_timezones:
    timezone = pytz.timezone(name)
    if not hasattr(timezone, '_tzinfos'):
        continue#skip, if some timezone doesn't have info
    # go thru tzinfo and see if short name like EDT and offset matches
    for (utcoffset, daylight, tzname), _ in timezone._tzinfos.iteritems():
        if utcoffset == local_offset and tzname == localtz:
            local_names.append(name)

print local_names

output:

['America/Atikokan', 'America/Bahia_Banderas', 'America/Bahia_Banderas', 'America/Belize', 'America/Cambridge_Bay', 'America/Cancun', 'America/Chicago', 'America/Chihuahua', 'America/Coral_Harbour', 'America/Costa_Rica', 'America/El_Salvador', 'America/Fort_Wayne', 'America/Guatemala', 'America/Indiana/Indianapolis', 'America/Indiana/Knox', 'America/Indiana/Marengo', 'America/Indiana/Marengo', 'America/Indiana/Petersburg', 'America/Indiana/Tell_City', 'America/Indiana/Vevay', 'America/Indiana/Vincennes', 'America/Indiana/Winamac', 'America/Indianapolis', 'America/Iqaluit', 'America/Kentucky/Louisville', 'America/Kentucky/Louisville', 'America/Kentucky/Monticello', 'America/Knox_IN', 'America/Louisville', 'America/Louisville', 'America/Managua', 'America/Matamoros', 'America/Menominee', 'America/Merida', 'America/Mexico_City', 'America/Monterrey', 'America/North_Dakota/Beulah', 'America/North_Dakota/Center', 'America/North_Dakota/New_Salem', 'America/Ojinaga', 'America/Pangnirtung', 'America/Rainy_River', 'America/Rankin_Inlet', 'America/Resolute', 'America/Resolute', 'America/Tegucigalpa', 'America/Winnipeg', 'CST6CDT', 'Canada/Central', 'Mexico/General', 'US/Central', 'US/East-Indiana', 'US/Indiana-Starke']

In production you can create such a mapping beforehand and save it instead of iterating always.

Testing script after changing timezone:

$ export TZ='Australia/Sydney' $ python get_tz_names.py ['Antarctica/Macquarie', 'Australia/ACT', 'Australia/Brisbane', 'Australia/Canberra', 'Australia/Currie', 'Australia/Hobart', 'Australia/Lindeman', 'Australia/Melbourne', 'Australia/NSW', 'Australia/Queensland', 'Australia/Sydney', 'Australia/Tasmania', 'Australia/Victoria']

Problem

How do I get the Olson timezone name (such as `Australia/Sydney`) corresponding to the value given by C's `localtime` call? This is the value overridden via `TZ`, by symlinking `/etc/localtime`, or setting a `TIMEZONE` variable in time-related system configuration files.

Original source

Related problems