Funciona para qualquer fuso horário, incluindo aqueles que observam o horário de verão (DST), ou seja, funciona para fusos horários que podem ter diferentes desvios de utc em momentos diferentes (deslocamento de utc não fixo). Não use tz.localize(datetime.now())- pode falhar durante a transição no final do horário de verão quando a hora local é ambígua.
Mas não há uma boa razão para que o fuso horário seja ingênuo - ele é especificado como UTC. Por que você precisa procurar uma biblioteca de terceiros para fazê-la funcionar corretamente?
Mark Ransom
4
Concordo; para mim, os tempos 'ingênuos' são completamente inúteis. No momento, há uma discussão na lista python sobre como adicionar pytz ao stdlib; o problema não é o licenciamento, mas o fato de os dados do fuso horário serem atualizados com tanta frequência (o que o próprio Python não pode ser). O pytz também não implementa a interface tzinfo da maneira esperada, para que você possa obter erros se tentar usar alguns dos fusos horários da cidade astimezone. Portanto, datetime não apenas não possui fusos horários nativos, mas a única implementação amplamente disponível do tzinfo não é compatível com o suposto padrão.
24910
5
@bobince Por que o pytz e as bibliotecas de data e hora padrão não funcionam para você? O núcleo e o pytz do Python, evoluindo como projetos independentes, reduzem a complexidade logística da equipe principal. Sim, reduzir a complexidade da equipe principal do Python aumenta a complexidade de todos os usuários do Python que precisam lidar com fusos horários, mas confio que eles tenham tomado essa decisão por um bom motivo. A regra "A biblioteca padrão não possui instâncias tzinfo ..." é ótima porque é simples, por que fazer uma exceção aqui?
Derek Litz
15
Que tal apenasu=datetime.now(pytz.utc)
Craig McQueen
4
@ banho: não use tz.localize(datetime.now()); use em datetime.now(tz)vez disso.
Qual é o preferido? datetime.now(timezone.utc)ou datetime.utcnow(timezone.utc)?
Jesse Webb
8
datetime.utcnow()não aceita argumentos. Então teria que ser datetime.now(timezone.utc).
Craig McQueen
1
datetime.now()retornará a hora da máquina, mas datetime.utcnow()retornará a hora UTC real.
Babu
13
@BuBu: datetime.utcnow()não definido tzinfopara indicar que é UTC. Mas datetime.now(datetime.timezone.utc)retorna a hora UTC comtzinfo set.
Craig McQueen
@CraigMcQueen Então, se passarmos um tzobjeto no construtor now, ele retornará o tempo desse fuso horário? Está bem! Obrigado por apontar.
Babu
71
As bibliotecas padrão do Python não incluem nenhuma classe tzinfo (mas consulte pep 431 ). Só posso adivinhar as razões. Pessoalmente, acho que foi um erro não incluir uma classe tzinfo para o UTC, porque essa é incontroversa o suficiente para ter uma implementação padrão.
Editar: Embora não exista implementação na biblioteca, existe um exemplo na tzinfodocumentação .
from datetime import timedelta, tzinfo
ZERO = timedelta(0)# A UTC class.class UTC(tzinfo):"""UTC"""def utcoffset(self, dt):return ZEROdef tzname(self, dt):return"UTC"def dst(self, dt):return ZERO
utc = UTC()
Para usá-lo, para obter o horário atual como um objeto de data e hora consciente:
from datetime import datetime
now = datetime.now(utc)
Existe datetime.timezone.utcno Python 3.2+:
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
Vai entender por que motivo esta classe não foi fornecido em primeiro lugar (e, mais importante, usado para datetimeobjetos criados por utcnow()) ...
André Caron
17
O objeto de fuso horário timezone.utcfoi finalmente adicionado ao Python 3.2. Para compatibilidade com versões anteriores, utcnow()ainda retorna um objeto de tempo sem fuso horário, mas você pode obter o que deseja chamando now(timezone.utc).
mhsmith
4
@rgove, esse é o tipo de correção de erros que deveria ser um jogo justo para o Python 3. Eles não deveriam ter se preocupado com a compatibilidade com versões anteriores. Há outro exemplo que li nos últimos dias - o structmódulo faria conversões automáticas de Unicode para bytestring e a decisão final foi quebrar a compatibilidade com versões anteriores do Python 3 para impedir que uma decisão ruim seguisse adiante.
@LS sim, pytzé um ótimo recurso. No momento em que editei minha resposta para inserir o código de exemplo, alguém já havia sugerido e eu não queria roubar seus trovões.
Mark Ransom
20
O pytzmódulo é uma opção e existe outra python-dateutil, que, embora também seja um pacote de terceiros, pode já estar disponível dependendo de suas outras dependências e sistema operacional.
Eu só queria incluir essa metodologia para referência - se você já instalou python-dateutilpara outros fins, pode usá-la em tzinfovez de duplicar compytz
import datetimeimport dateutil.tz# Get the UTC time with datetime.now:
utcdt = datetime.datetime.now(dateutil.tz.tzutc())# Get the UTC time with datetime.utcnow:
utcdt = datetime.datetime.utcnow()
utcdt = utcdt.replace(tzinfo=dateutil.tz.tzutc())# For fun- get the local time
localdt = datetime.datetime.now(dateutil.tz.tzlocal())
Costumo concordar que as chamadas para utcnowdevem incluir as informações do fuso horário UTC. Suspeito que isso não esteja incluído porque a biblioteca de data / hora nativa é padronizada como data / hora ingênua para compatibilidade cruzada.
Eu estava usando a chamada datetime.datetime.utcfromtimestamp () e precisando adicionar o tzinfo. A segunda solução funcionou para mim: utcdt = datetime.datetime.utcfromtimestamp(1234567890).replace(dateutil.tz.tzutc())
Desde o meu programa já estava importando dateutilpara dateutil.parser, eu gostei esta solução melhor. Era tão simples como: utcCurrentTime = datetime.datetime.now(tz=dateutil.tz.tzutc()). Viola!!
De fato, a API de data e hora do Python sempre retorna objetos de data e hora desconhecidos, o que é muito lamentável. De fato, assim que você obtém um desses objetos, não há como saber qual é o fuso horário; portanto, esses objetos são "inúteis" por si próprios.
Infelizmente, mesmo que você possa usá- utcnow()lo, ainda não verá as informações do fuso horário, como descobriu.
Recomendações:
Sempre use datetimeobjetos conscientes , ou seja, com informações de fuso horário. Isso garante que você possa compará-los diretamente ( datetime
objetos conscientes e inconscientes não são comparáveis) e os retornará corretamente aos usuários. Aproveite o pytz para ter objetos de fuso horário.
Use ISO 8601 como formato de sequência de entrada e saída. Use datetime.datetime.isoformat()para retornar os carimbos de data e hora como string formatada usando esse formato, que inclui as informações do fuso horário.
Se você precisar analisar seqüências de caracteres contendo carimbos de data e hora no formato ISO 8601, poderá confiar nele iso8601, que retornará carimbos de data e hora com informações corretas do fuso horário. Isso torna os timestamps diretamente comparáveis.
Essa é uma recomendação um pouco enganadora. A regra geral é, nunca lide com fusos horários. Sempre armazene e transmita tz objetos unc utc (objetos de época). Fuso horário só deve ser calculada no momento da representação na UI
Nehem
1
Parece que já combina com os pensamentos de Julien muito bem. Quais de suas recomendações específicas (como mencionado acima) são enganosas?
31517 Joe D'Andrea
10
Para adicionar timezoneinformações no Python 3.2 ou superior
import datetime>>> d = datetime.datetime.now(tz=datetime.timezone.utc)>>>print(d.tzinfo)'UTC+00:00'
Até onde eu sei , em docs.python.org/library/datetime.html , um datetime sem um tzinfo é aquele em que o fuso horário não é especificado. Aqui o fuso horário tem sido especificado, então logicamente que deve estar presente. Há uma grande diferença entre uma data / hora sem um fuso horário associado e outra que esteja definitivamente no UTC. (Idealmente, devem ser diferentes tipos da OMI, mas isso é outro assunto ...)
Jon Skeet
@ JonSkeet Acho que você está perdendo o ponto de Ignacio de que o UTC não é um fuso horário. Incrível que esta resposta tem -9 pontuação como eu escreva isso ...
CS
3
@ CS: Bem, Ignacio nunca afirmou que ... e, embora estritamente falando, o UTC não seja um fuso horário, geralmente é tratado como um para tornar a vida consideravelmente mais simples (inclusive em Python, por exemplo, com pytz.utc). Observe que há uma grande diferença entre um valor cujo deslocamento em relação ao UTC é desconhecido e um em que se sabe que é 0. O último é o que utcnow()deve retornar, IMO. Isso se encaixaria com "Um objeto consciente é usado para representar um momento específico no tempo que não está aberto à interpretação", conforme a documentação.
Respostas:
Isso significa que é um fuso horário ingênuo, então você não pode usá-lo com
datetime.astimezone
você pode atribuir um fuso horário como este
agora você pode mudar de fuso horário
Para obter a hora atual em um determinado fuso horário, você pode passar o tzinfo para
datetime.now()
diretamente:Funciona para qualquer fuso horário, incluindo aqueles que observam o horário de verão (DST), ou seja, funciona para fusos horários que podem ter diferentes desvios de utc em momentos diferentes (deslocamento de utc não fixo). Não use
tz.localize(datetime.now())
- pode falhar durante a transição no final do horário de verão quando a hora local é ambígua.fonte
astimezone
. Portanto, datetime não apenas não possui fusos horários nativos, mas a única implementação amplamente disponível do tzinfo não é compatível com o suposto padrão.u=datetime.now(pytz.utc)
tz.localize(datetime.now())
; use emdatetime.now(tz)
vez disso.Observe que, para o Python 3.2 em diante, o
datetime
módulo contémdatetime.timezone
. A documentação paradatetime.utcnow()
diz:Então você pode fazer:
fonte
datetime.now(timezone.utc)
oudatetime.utcnow(timezone.utc)
?datetime.utcnow()
não aceita argumentos. Então teria que serdatetime.now(timezone.utc)
.datetime.now()
retornará a hora da máquina, masdatetime.utcnow()
retornará a hora UTC real.datetime.utcnow()
não definidotzinfo
para indicar que é UTC. Masdatetime.now(datetime.timezone.utc)
retorna a hora UTC comtzinfo
set.tz
objeto no construtor now, ele retornará o tempo desse fuso horário? Está bem! Obrigado por apontar.As bibliotecas padrão do Python não incluem nenhuma classe tzinfo (mas consulte pep 431 ). Só posso adivinhar as razões. Pessoalmente, acho que foi um erro não incluir uma classe tzinfo para o UTC, porque essa é incontroversa o suficiente para ter uma implementação padrão.
Editar: Embora não exista implementação na biblioteca, existe um exemplo na
tzinfo
documentação .Para usá-lo, para obter o horário atual como um objeto de data e hora consciente:
Existe
datetime.timezone.utc
no Python 3.2+:fonte
datetime
objetos criados porutcnow()
) ...timezone.utc
foi finalmente adicionado ao Python 3.2. Para compatibilidade com versões anteriores,utcnow()
ainda retorna um objeto de tempo sem fuso horário, mas você pode obter o que deseja chamandonow(timezone.utc)
.struct
módulo faria conversões automáticas de Unicode para bytestring e a decisão final foi quebrar a compatibilidade com versões anteriores do Python 3 para impedir que uma decisão ruim seguisse adiante.tzinfo
documentação do Python inclua exemplos de código para implementá-lo, mas eles não incluem essa funcionalidade no próprio datetime! docs.python.org/2/library/datetime.html#datetime.tzinfo.fromutcpytz
é um ótimo recurso. No momento em que editei minha resposta para inserir o código de exemplo, alguém já havia sugerido e eu não queria roubar seus trovões.O
pytz
módulo é uma opção e existe outrapython-dateutil
, que, embora também seja um pacote de terceiros, pode já estar disponível dependendo de suas outras dependências e sistema operacional.Eu só queria incluir essa metodologia para referência - se você já instalou
python-dateutil
para outros fins, pode usá-la emtzinfo
vez de duplicar compytz
Costumo concordar que as chamadas para
utcnow
devem incluir as informações do fuso horário UTC. Suspeito que isso não esteja incluído porque a biblioteca de data / hora nativa é padronizada como data / hora ingênua para compatibilidade cruzada.fonte
utcdt = datetime.datetime.utcfromtimestamp(1234567890).replace(dateutil.tz.tzutc())
datetime.now(pytz_tz)
que sempre funciona;datetime.now(dateutil.tz.tzlocal())
pode falhar durante transições de horário de verão . PEP 495 - A desambiguação na hora local pode melhorar adateutil
situação no futuro.utc_dt = datetime.fromtimestamp(1234567890, dateutil.tz.tzutc())
(nota:dateutil
com um deslocamento utc não fixo (comodateutil.tz.tzlocal()
) pode falhar aqui , use umapytz
solução baseada em vez ).dateutil
paradateutil.parser
, eu gostei esta solução melhor. Era tão simples como:utcCurrentTime = datetime.datetime.now(tz=dateutil.tz.tzutc())
. Viola!!Julien Danjou escreveu um bom artigo explicando por que você nunca deve lidar com fusos horários . Um trecho:
Infelizmente, mesmo que você possa usá-
utcnow()
lo, ainda não verá as informações do fuso horário, como descobriu.Recomendações:
fonte
Para adicionar
timezone
informações no Python 3.2 ou superiorfonte
AttributeError: 'module' object has no attribute 'timezone'
Python 2.7.13 (padrão, 19 de janeiro de 2017, 14:48:08)fonte
As datas UTC não precisam de nenhuma informação de fuso horário, pois são UTC, o que, por definição, significa que elas não têm deslocamento.
fonte
pytz.utc
). Observe que há uma grande diferença entre um valor cujo deslocamento em relação ao UTC é desconhecido e um em que se sabe que é 0. O último é o queutcnow()
deve retornar, IMO. Isso se encaixaria com "Um objeto consciente é usado para representar um momento específico no tempo que não está aberto à interpretação", conforme a documentação.