Estou tentando subtrair um valor de data do valor de datetime.today()
para calcular há quanto tempo algo estava. Mas reclama:
TypeError: can't subtract offset-naive and offset-aware datetimes
O valor datetime.today()
não parece "consciente do fuso horário", enquanto o meu outro valor de data é. Como obtenho um valor datetime.today()
ciente do fuso horário?
No momento, está me dando a hora no horário local, que é PST, ou seja, UTC - 8 horas. Na pior das hipóteses, existe uma maneira de inserir manualmente um valor de fuso horário no datetime
objeto retornado por datetime.today()
e defini-lo como UTC-8?
Obviamente, a solução ideal seria conhecer automaticamente o fuso horário.
datetime.now().astimezone()
desde Python 3.6Respostas:
Na biblioteca padrão, não há uma maneira multiplataforma de criar fusos horários conscientes sem criar sua própria classe de fuso horário.
No Windows, existe
win32timezone.utcnow()
, mas isso faz parte do pywin32. Prefiro sugerir o uso da biblioteca pytz , que possui um banco de dados constantemente atualizado da maioria dos fusos horários.Trabalhar com fusos horários locais pode ser muito complicado (consulte os links de "Leituras adicionais" abaixo), portanto, você pode usar o UTC em todo o aplicativo, especialmente para operações aritméticas, como calcular a diferença entre dois pontos no tempo.
Você pode obter a data / hora atual da seguinte forma:
Lembre-se disso
datetime.today()
edatetime.now()
retorne a hora local , não a hora UTC, portanto, aplicar.replace(tzinfo=pytz.utc)
a eles não seria correto.Outra boa maneira de fazer isso é:
que é um pouco mais curto e faz o mesmo.
Leitura / observação adicional por que preferir o UTC em muitos casos:
fonte
datetime.now(pytz.utc)
vez dedatetime.utcnow().replace(tzinfo = pytz.utc)
?now(utc)
não retorna hoje (a menos que seja meia-noite no UTC), retorna o horário atual no UTC. Você precisa também.replace(hour=0, minute=0, ...)
de obter o início do dia (comodatetime.today()
)today()
retorna o horário atual, não a meia-noite. Se houver um caso de uso em que a meia-noite é necessária, sim, a substituição precisará ser feita de acordo. Como a pergunta original era sobre diferença de data e hora, não acho que seja necessária meia-noite.datetime.today()
écombine(date.today(), time())
.datetime
possui métodos.now()
e.today()
métodos que (como você apontou corretamente) retornam (quase) a mesma coisa. Não existedate.now()
método.date
edatetime
objetos não são intercambiáveis. Usar um objeto datetime em vez de umdate
objeto pode produzir erros sutis; Não vejo nenhuma razão paradatetime.today()
existir se for quase uma duplicata dedatetime.now()
.timezone.now()
vez de,datetime.now()
pois ele usará o UTC automaticamente seUSE_TZ = True
.timezone
é localizar emdjango.utils.timezone
, documentação: docs.djangoproject.com/en/1.11/topics/i18n/timezonesObtenha a hora atual, em um fuso horário específico:
fonte
datetime.datetime(2016, 11, 5, 9, 43, 45, tzinfo=pytz.timezone('US/Pacific'))
e ver se é isso que você esperavaNo Python 3, a biblioteca padrão facilita muito a especificação do UTC como o fuso horário:
Se você deseja uma solução que use apenas a biblioteca padrão e que funcione no Python 2 e no Python 3, consulte a resposta do jfs .
Se você precisar do fuso horário local, não do UTC, consulte a resposta de Mihai Capotă
fonte
Aqui está uma solução stdlib que funciona em Python 2 e 3:
onde
today
é uma instância de data e hora consciente que representa o início do dia (meia-noite) no UTC eutc
é um objeto tzinfo ( exemplo da documentação ):Relacionado: comparação de desempenho de várias maneiras de obter a meia-noite (início de um dia) para um determinado horário UTC . Nota: é mais complexo chegar meia-noite para um fuso horário com um deslocamento UTC não fixo .
fonte
Outro método para construir o objeto datetime com reconhecimento de fuso horário que representa o horário atual:
fonte
pytz.utc
epytz.UTC
são ambos definidos (e são as mesmas)replace()
fuso horário geralmente é propenso a erros na maioria dos outros usos, enquanto olocalize()
ing é a maneira preferida de atribuir o fuso horário a registros de data e hora ingênuos..localize()
método falha para horários locais ambíguos (entrada não utc). A resposta da @ philfreo que usa.now(pytz_timezone)
continua a funcionar nesses casos..now(pytz_timezone)
faz exatamente o mesmo quelocalize(utcnow)
- primeiro, gera o horário atual no UTC, depois atribui a ele um fuso horário: "<...> Nesse caso, o resultado é equivalente atz.fromutc(datetime.utcnow().replace(tzinfo=tz))
". Ambas as respostas estão corretas e funcionam sempre.pytz
através do OLSON db, deve saber como convertê-lo em qualquer fuso horário do mundo. Tornar ciente de qualquer outro fuso horário ingênuo (não utc) é difícil por causa da ambiguidade durante os turnos de verão. Isso não é problema.localize
(alimentar umis_dst
valor faz com que funcione em qualquer data). Esse é um problema inerente à prática de horário de verão.Um one-liner usando apenas a biblioteca padrão funciona a partir do Python 3.3. Você pode obter um
datetime
objeto com reconhecimento de fuso horário local usandoastimezone
(como sugerido por johnchen902 ):fonte
datetime.now()
pode ser chamado sem argumentos e retornar o resultado local correto (datetime
presume-se que ingênuos s estejam no fuso horário local).Se você estiver usando o Django , poderá definir datas sem reconhecimento de tz (somente UTC ).
Comente a seguinte linha em settings.py:
fonte
O pytz é uma biblioteca Python que permite cálculos precisos e de fuso horário entre plataformas usando o Python 2.3 ou superior.
Com o stdlib, isso não é possível.
Veja uma pergunta semelhante no SO .
fonte
Aqui está uma maneira de gerá-lo com o stdlib:
date armazenará a data local e o deslocamento do UTC , não a data no fuso horário UTC, para que você possa usar esta solução se precisar identificar em qual fuso horário a data é gerada . Neste exemplo e no meu fuso horário local:
A chave é adicionar a
%z
diretiva à representação FORMAT, para indicar o deslocamento UTC da estrutura de tempo gerada. Outros formatos de representação podem ser consultados nos documentos do módulo datetimeSe você precisar da data no fuso horário UTC, poderá substituir time.localtime () por time.gmtime ()
Editar
Isso funciona apenas em python3 . A diretiva z não está disponível no código _strptime.py do python 2
fonte
Use dateutil, conforme descrito em Python datetime.datetime.now (), que reconhece o fuso horário :
fonte
tzlocal()
função ainda é uma das soluções mais simples e definitivamente deve ser mencionada aqui.Obter uma data com reconhecimento de
utc
fuso horário no fuso horário é suficiente para que a subtração de data funcione.Mas se você deseja uma data com reconhecimento de fuso horário no seu fuso horário atual,
tzlocal
é o caminho a seguir:O PS
dateutil
tem uma função semelhante (dateutil.tz.tzlocal
). Mas apesar de compartilhar o nome, ele tem uma base de código completamente diferente, que conforme observado por JF Sebastian pode dar resultados errados.fonte
Aqui está uma solução usando um fuso horário legível e que funciona com today ():
Você pode listar todos os fusos horários da seguinte maneira:
fonte
Especialmente para fusos horários não UTC:
O único fuso horário que possui seu próprio método é
timezone.utc
, mas você pode alterar um fuso horário com qualquer deslocamento UTC, se precisar, usandotimedelta
&timezone
e forçando-o usando.replace
.Usar
timezone(timedelta(hours=n))
como fuso horário é a verdadeira bala de prata aqui, e possui muitos outros aplicativos úteis.fonte
Se você obtiver data e hora atuais no python, importe a data e a hora, o pacote pytz no python depois de obter a data e a hora atuais como ..
fonte
Outra alternativa, na minha opinião uma melhor, é usar em
Pendulum
vez depytz
. Considere o seguinte código simples:Para instalar o Pendulum e ver a documentação deles, clique aqui . Possui inúmeras opções (como suporte simples ao formato ISO8601, RFC3339 e muitos outros), melhor desempenho e tende a gerar código mais simples.
fonte
Use o fuso horário, como mostrado abaixo, para uma data e hora com reconhecimento de fuso horário. O padrão é UTC:
fonte
Tyler, de 'howchoo', fez um ótimo artigo que me ajudou a ter uma idéia melhor dos Objetos do Datetime, link abaixo
Trabalhando com data e hora
essencialmente, acabei de adicionar o seguinte ao final dos meus objetos datetime
Exemplo:
fonte
tente pnp_datetime , todo o tempo usado e retornado está no fuso horário e não causará nenhum problema que seja ingênuo e sensível ao deslocamento.
fonte
Deve-se enfatizar que, desde o Python 3.6, você só precisa da lib padrão para obter um objeto datetime com reconhecimento de fuso horário que represente a hora local (a configuração do seu sistema operacional). Usando astimezone ()
(veja o comentário de @ johnchen902).
fonte