Existe uma lista de fusos horários de Pytz?

659

Gostaria de saber quais são todos os valores possíveis para o argumento de fuso horário na biblioteca Python pytz. Como fazer isso?

ipegasus
fonte
6
É engraçado como "GMT", "GMT + 0", "GMT-0", "GMT0", "Greenwich", "UCT", "UTC", "Universal" e "Zulu" significam basicamente a mesma coisa e ainda existem muitas entradas para isso.
Joe Z.
43
GMT não é o mesmo que UTC. É um erro comum.
PawelRoman
1
@PawelRoman: GMT pode significar coisas diferentes em um contexto diferente. Ele faz UTC média, por vezes, por exemplo, cordas de tempo de certificado SSL, como aceitou requer GMT ( legado). ssl.cert_time_to_second() ASN1_TIME_print()
JFS
3
@PawelRoman, você está certo no sentido de que um é um fuso horário e o outro é um padrão. Mas, no sentido prático em que a maioria das pessoas pensa, ambas se referem ao mesmo momento no tempo.
rob
1
@YongweiWu ver stackoverflow.com/questions/11473721/...
Mark Ransom

Respostas:

318

Você pode listar todos os fusos horários disponíveis com pytz.all_timezones:

In [40]: import pytz
In [41]: pytz.all_timezones
Out[42]: 
['Africa/Abidjan',
 'Africa/Accra',
 'Africa/Addis_Ababa',
 ...]

Há também pytz.common_timezones:

In [45]: len(pytz.common_timezones)
Out[45]: 403

In [46]: len(pytz.all_timezones)
Out[46]: 563
unutbu
fonte
9
Além disso all_timezones, o pytz também fornece common_timezones .
Mark Hildreth
3
por que a China está faltando?
Adders
4
A China usa um único fuso horário , cujo nome é fuso horário 'Asia/Shanghai'.
Unutbu
1
Esta expressão mostra o terrível resultado que o pytz pode fornecer: (datetime(2017,2,13,14,29,29, tzinfo=pytz.timezone('Asia/Shanghai')) - datetime(2017,2,13,14,29,29, tzinfo=pytz.timezone('UTC'))).total_seconds()(o resultado não é -28800). Evitarei que o pytz - datautil.tz forneça funcionalidades semelhantes, mas use o banco de dados de fuso horário do SO e não tenha esses problemas.
Yongwei Wu
2
@YongweiWu, é um uso incorreto da API. Você não deve passar um fuso horário pytz com um deslocamento utc não fixo como argumento tzinfo diretamente. Use o método .localize () como sugerem os documentos do pytz.
JFS
38

Não crie sua própria lista - pytzpossui um conjunto interno:

import pytz
set(pytz.all_timezones_set)  
>>> {'Europe/Vienna', 'America/New_York', 'America/Argentina/Salta',..}

Você pode aplicar um fuso horário :

import datetime
tz = pytz.timezone('Pacific/Johnston')
ct = datetime.datetime.now(tz=tz)
>>> ct.isoformat()
2017-01-13T11:29:22.601991-05:00

Ou se você já possui um datetimeobjeto que reconhece a TZ (não é ingênuo):

# This timestamp is in UTC
my_ct = datetime.datetime.now(tz=pytz.UTC)

# Now convert it to another timezone
new_ct = my_ct.astimezone(tz)
>>> new_ct.isoformat()
2017-01-13T11:29:22.601991-05:00
chribsen
fonte
27

O nome do fuso horário é a única maneira confiável de especificar o fuso horário.

Você pode encontrar uma lista de nomes de fuso horário aqui: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones Observe que esta lista contém muitos nomes de alias, como EUA / Leste, para o fuso horário chamado América / New_York.

Se você desejar criar programaticamente essa lista a partir do banco de dados zoneinfo, poderá compilá-la no arquivo zone.tab no banco de dados zoneinfo. Não acho que o pytz tenha uma API para obtê-los, e também não acho que seria muito útil.

Lennart Regebro
fonte
14

Aqui, lista Python de códigos de países, nomes, continentes, capitais e fusos horários de pytz.

countries = [
{'timezones': ['Europe/Paris'], 'code': 'FR', 'continent': 'Europe', 'name': 'France', 'capital': 'Paris'}
{'timezones': ['Africa/Kampala'], 'code': 'UG', 'continent': 'Africa', 'name': 'Uganda', 'capital': 'Kampala'},
{'timezones': ['Asia/Colombo'], 'code': 'LK', 'continent': 'Asia', 'name': 'Sri Lanka', 'capital': 'Sri Jayewardenepura Kotte'},
{'timezones': ['Asia/Riyadh'], 'code': 'SA', 'continent': 'Asia', 'name': 'Saudi Arabia', 'capital': 'Riyadh'},
{'timezones': ['Africa/Luanda'], 'code': 'AO', 'continent': 'Africa', 'name': 'Angola', 'capital': 'Luanda'},    
{'timezones': ['Europe/Vienna'], 'code': 'AT', 'continent': 'Europe', 'name': 'Austria', 'capital': 'Vienna'},
{'timezones': ['Asia/Calcutta'], 'code': 'IN', 'continent': 'Asia', 'name': 'India', 'capital': 'New Delhi'},
{'timezones': ['Asia/Dubai'], 'code': 'AE', 'continent': 'Asia', 'name': 'United Arab Emirates', 'capital': 'Abu Dhabi'},
{'timezones': ['Europe/London'], 'code': 'GB', 'continent': 'Europe', 'name': 'United Kingdom', 'capital': 'London'},
]

Para lista completa: Gist Github

Espero que ajude.

Jay Modi
fonte
4

Eles parecem estar preenchidos pelos fusos horários do banco de dados tz encontrados aqui .

insira a descrição da imagem aqui

Chris Redford
fonte
1
pytzfornece acesso ao banco de dados tz (é a fonte dos dados da wikipedia).
JFS
4

EDIT: Eu agradeceria se você não reduzir ainda mais esta resposta. Esta resposta está errada , mas prefiro mantê-la como uma nota histórica. Embora seja discutível se a interface pytz é propensa a erros, ela pode fazer coisas que o dateutil.tz não pode, principalmente no que se refere ao horário de verão no passado ou no futuro. Gravei honestamente minha experiência em um artigo "Fusos horários no Python" .


Se você estiver em uma plataforma semelhante ao Unix, sugiro que você evite o pytz e consulte apenas / usr / share / zoneinfo. dateutil.tz pode utilizar as informações lá.

O seguinte trecho de código mostra o problema que o pytz pode dar. Fiquei chocado quando descobri. (Curiosamente, o pytz instalado pelo yum no CentOS 7 não apresenta esse problema.)

import pytz
import dateutil.tz
from datetime import datetime
print((datetime(2017,2,13,14,29,29, tzinfo=pytz.timezone('Asia/Shanghai'))
     - datetime(2017,2,13,14,29,29, tzinfo=pytz.timezone('UTC')))
     .total_seconds())
print((datetime(2017,2,13,14,29,29, tzinfo=dateutil.tz.gettz('Asia/Shanghai'))
     - datetime(2017,2,13,14,29,29, tzinfo=dateutil.tz.tzutc()))
     .total_seconds())

-29160.0
-28800.0

Ou seja, o fuso horário criado por pytz é para a verdadeira hora local, em vez da hora local padrão observada pelas pessoas. Xangai está em conformidade com +0800, não +0806, conforme sugerido por pytz:

pytz.timezone('Asia/Shanghai')
<DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>

Edição: Graças ao comentário de Mark Ransom e voto negativo, agora eu sei que estou usando pytz da maneira errada. Em resumo, você não deve passar o resultado de pytz.timezone(…)para datetime, mas deve passar o datetimepara seu localizemétodo.

Apesar do argumento dele (e do meu mal por não ler a documentação do pytz com mais cuidado), vou manter essa resposta. Eu estava respondendo à pergunta de uma maneira (como enumerar os fusos horários suportados, embora não com o pytz), porque acreditava que o pytz não fornecia uma solução correta. Embora minha crença estivesse errada, essa resposta ainda está fornecendo algumas informações, IMHO, que são potencialmente úteis para as pessoas interessadas nesta questão. A maneira correta de Pytz de fazer as coisas é contra-intuitiva. Heck, se o tzinfo criado por pytz não deve ser usado diretamente por datetime, deve ser um tipo diferente. A interface pytz é simplesmente mal projetada. O link fornecido por Mark mostra que muitas pessoas, não apenas eu, foram enganadas pela interface pytz.

Yongwei Wu
fonte
2
Consulte stackoverflow.com/questions/11473721/… para uma correção. Não há nada errado pytz, você está apenas usando errado. PS Esta não é uma resposta para a pergunta em tudo .
Mark Ransom
1
@ MarkRansom Boas informações, e é bom saber. No entanto, eu não acredito no seu argumento. A interface foi projetada incorretamente, ponto final. É muito contra-intuitivo.
Yongwei Wu
3
Sim, a interface foi projetada incorretamente. Mas é a datetimeinterface que está errada, não pytz. datetimenão antecipou objetos inteligentes de fuso horário, portanto, sua interface não os inicializa corretamente.
Mark Ransom
1
Com respeito, eu discordo. datetimefaz parte da biblioteca padrão do Python e é o pytz que deve seguir a datetimeinterface, e não o contrário. Se alguém pudesse implementar alguma interface da maneira que pensa melhor sem consenso, não haveria software robusto.
Yongwei Wu
2
Como eu disse, pytznão é possível seguir a datetimeinterface porque ela datetimeé deficiente. Os autores dessa interface não anteciparam os problemas de um fuso horário cujos parâmetros mudam ao longo dos anos. Só porque faz parte da distribuição padrão do Python não significa que seja perfeito.
Mark Ransom
-8

Na minha opinião, esta é uma falha de design da biblioteca pytz. Deve ser mais confiável especificar um fuso horário usando o deslocamento, por exemplo

pytz.construct("UTC-07:00")

que fornece o fuso horário do Canadá / Pacífico.

Jinghui Niu
fonte
12
As compensações mudam ao longo do ano (geralmente por causa do horário de verão), portanto não é o mesmo que normalmente pensamos como fuso horário.
Ryan Hiebert 21/09/16
A sintaxe escolhida é baseada nas definições em tzdata .
Brad Koch