19

I'm using pytz. I've read through the entire documentation sheet, but didn't see how this could be done.

I have a timezone: America/Chicago. All I want is to get the respective country code for this timezone: US.

It shows that I can do the opposite, such as:

>>> country_timezones('ch')
['Europe/Zurich']
>>> country_timezones('CH')
['Europe/Zurich']

but I need to do it the other way around.

Can this be done in Python, using pytz (or any other way for that matter)?

Snowman
  • 31,411
  • 46
  • 180
  • 303

2 Answers2

25

You can use the country_timezones object from pytz and generate an inverse mapping:

from pytz import country_timezones

timezone_country = {}
for countrycode in country_timezones:
    timezones = country_timezones[countrycode]
    for timezone in timezones:
        timezone_country[timezone] = countrycode

Now just use the resulting dictionary:

>>> timezone_country['Europe/Zurich']
u'CH'
jsalonen
  • 29,593
  • 15
  • 91
  • 109
  • it would break if the same timezone name is used in different countries. There are no such names in `country_timezones`. But some common timezones are not in it e.g., UTC, US/Central, US/Eastern, Canada/Central, etc – jfs Oct 22 '12 at 22:46
  • @J.F.Sebastian what did you mean by your last sentence? Those timezones are not in what? – Snowman Oct 22 '12 at 22:51
  • All timezones defined in `pytz` map to exactly one country. Thus, it doesn't break. – jsalonen Oct 22 '12 at 22:53
  • @mohabitar: those timezones are not in `country_timezones` values therefore `timezone_country` that is generated using `country_timezones` will produce KeyError for UTC, US/Central, etc. – jfs Oct 22 '12 at 22:56
  • I don't understand what's the problem here. He didn't ask to include general purpose timezones like `UTC` into the mapping. – jsalonen Oct 22 '12 at 22:57
  • @J.F.Sebastian thats odd, why are those timezones not included? Arent they common enough? – Snowman Oct 22 '12 at 22:59
  • @mohabitar: they are not included, because the don't exist in `pytz.country_timezones` – jsalonen Oct 22 '12 at 23:01
  • @J.F.Sebastian so should I check `if 'Europe/Zurich' in timezone_country` before accessing the value? – Snowman Oct 22 '12 at 23:07
  • 1
    @mohabitar: if you use timezones that are not in `country_timezones` values then yes, such timezones require other solution – jfs Oct 22 '12 at 23:13
6

This is easy. You have a dict mapping each country to a list of timezones. You want to map each list member back to the dict.

Rather than just give the answer, let's see how to get it.

First, if you just had a dict mapping each country to a single timezone, this would be a simple reverse mapping:

timezone_countries = {timezone: country 
                      for country, timezone in country_timezones.iteritems()}

But this won't work; you have a mapping to a list of timezones, and you want each timezone in that list to map back to the country. That English description "each timezone in that list" is trivially translatable to Python:

timezone_countries = {timezone: country 
                      for country, timezones in country_timezones.iteritems()
                      for timezone in timezones}

Here it is in action:

>>> from pytz import country_timezones
>>> timezone_countries = {timezone: country 
                          for country, timezones in country_timezones.iteritems()
                          for timezone in timezones}
>>> timezone_countries['Europe/Zurich']
u'CH'

Side note: You didn't mention Python 2 vs. 3, so I assumed 2. If you're on 3, change iteritems to items, and the output will be 'CH' instead of u'CH'.

Community
  • 1
  • 1
abarnert
  • 354,177
  • 51
  • 601
  • 671