Получить код страны для часового пояса с помощью pytz?

Я использую pytz. Я прочитал весь лист документации, но не понял, как это можно сделать.

У меня часовой пояс: Америка/Чикаго. Все, что я хочу, это получить соответствующий код страны для этого часового пояса: США.

Это показывает, что я могу сделать обратное, например:

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

но мне нужно сделать это наоборот.

Можно ли это сделать на Python, используя pytz (или любым другим способом)?


person Snowman    schedule 22.10.2012    source источник


Ответы (2)


Вы можете использовать объект country_timezones из pytz и создать обратное отображение:

from pytz import country_timezones

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

Теперь просто используйте полученный словарь:

>>> timezone_country['Europe/Zurich']
u'CH'
person jsalonen    schedule 22.10.2012
comment
это сломается, если одно и то же имя часового пояса используется в разных странах. В country_timezones таких имен нет. Но некоторые общие часовые пояса не включены в него, например, UTC, US/Central, US/Eastern, Canada/Central и т. д. - person jfs; 23.10.2012
comment
@ J.F.Sebastian, что ты имел в виду под своим последним предложением? Эти часовые пояса не в чем? - person Snowman; 23.10.2012
comment
Все часовые пояса, определенные в pytz, соответствуют только одной стране. Таким образом, он не ломается. - person jsalonen; 23.10.2012
comment
@mohabitar: эти часовые пояса не находятся в значениях country_timezones, поэтому timezone_country, сгенерированный с использованием country_timezones, выдаст KeyError для UTC, US/Central и т. д. - person jfs; 23.10.2012
comment
Я не понимаю, в чем здесь проблема. Он не просил включать часовые пояса общего назначения, такие как UTC, в сопоставление. - person jsalonen; 23.10.2012
comment
@ J.F.Sebastian, это странно, почему эти часовые пояса не включены? Разве они не достаточно распространены? - person Snowman; 23.10.2012
comment
@mohabitar: они не включены, потому что их нет в pytz.country_timezones - person jsalonen; 23.10.2012
comment
@ J.F.Sebastian, так должен ли я проверить if 'Europe/Zurich' in timezone_country перед доступом к значению? - person Snowman; 23.10.2012
comment
@mohabitar: если вы используете часовые пояса, которые не входят в значения country_timezones, то да, такие часовые пояса требуют другого решения - person jfs; 23.10.2012

Это просто. У вас есть dict сопоставление каждой страны со списком часовых поясов. Вы хотите отобразить каждого члена list обратно в dict.

Вместо того, чтобы просто дать ответ, давайте посмотрим, как его получить.

Во-первых, если бы у вас было только dict, отображающее каждую страну в один часовой пояс, это было бы простое обратное сопоставление:

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

Но это не сработает; у вас есть сопоставление со списком часовых поясов, и вы хотите, чтобы каждый часовой пояс в этом списке сопоставлялся со страной. Это английское описание «каждый часовой пояс в этом списке» тривиально переводится на Python:

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

Вот он в действии:

>>> 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'

Примечание: вы не упомянули Python 2 против 3, поэтому я предположил 2. Если вы используете 3, измените iteritems на items, и на выходе будет 'CH' вместо u'CH'.

person abarnert    schedule 22.10.2012