Eu tenho dt = datetime(2013,9,1,11)
e gostaria de obter um registro de data e hora do Unix desse objeto datetime.
Quando eu (dt - datetime(1970,1,1)).total_seconds()
recebi o timestamp 1378033200
.
Ao convertê-lo novamente usando datetime.fromtimestamp
eu consegui datetime.datetime(2013, 9, 1, 6, 0)
.
A hora não corresponde. O que eu perdi aqui?
timestamp
método em vez de tentar fazer isso sozinho. Por um lado, isso evita completamente a possibilidade de subtrair tempos ingênuos de diferentes fusos horários.dt
vem? É uma hora local ou horário no UTC?Respostas:
O que você perdeu aqui é o fuso horário.
Presumivelmente, você tem cinco horas de folga no UTC, portanto, 2013-09-01T11: 00: 00 local e 2013-09-01T06: 00: 00Z são o mesmo horário.
Você precisa ler a parte superior dos
datetime
documentos, que explica os fusos horários e os objetos "ingênuos" e "conscientes".Se o seu data e hora ingênuo original era UTC, a maneira de recuperá-lo é usar em
utcfromtimestamp
vez defromtimestamp
.Por outro lado, se o seu data e hora ingênuo original fosse local, você não deveria ter subtraído um carimbo de data / hora UTC dele em primeiro lugar; use em
datetime.fromtimestamp(0)
vez disso.Ou, se você tivesse um objeto de data e hora consciente, precisará usar uma época local (consciente) dos dois lados ou converter explicitamente para e do UTC.
Se você possui ou pode atualizar para o Python 3.3 ou posterior, pode evitar todos esses problemas apenas usando o
timestamp
método em vez de tentar descobrir como fazê-lo. E mesmo se não o fizer, considere emprestar seu código-fonte .(E se você pode esperar pelo Python 3.4, parece que o PEP 341 provavelmente chegará ao lançamento final, o que significa que todas as coisas sobre as quais JF Sebastian e eu estávamos falando nos comentários devem ser possíveis apenas com o stdlib, e trabalhando da mesma maneira no Unix e no Windows.)
fonte
dt
estiver no fuso horário local, a fórmula na pergunta está incorretadatetime.fromtimestamp(0)
(época no fuso horário atual) deve ser usada em vez dedatetime(1970, 1,1)
(época unix no UTC).fromtimestamp(0)
pode falhar se o sistema não armazenar informações históricas do fuso horário, por exemplo, no Windows.pytz
poderia ser usado neste caso.pytz
não ajuda, a menos que você já saiba em que fuso horário está; para fazer isso programaticamente, você precisa de uma biblioteca diferente que obtenha o fuso horário atual do Windows e o converta em umpytz
fuso horário e / ou procure pelo nome.tzlocal
módulo que também funciona no Windows. Veja como você pode converter a hora utc na hora local .solução é
fonte
d
é um objeto ingênuo de data / data e hora que representa a hora local (pode falhar em horários ambíguos ou em datas passadas / futuras se o SO não fornecer um histórico tz db (o deslocamento UTC pode ter sido diferente no passado no local) fuso horário)). Mais opções .Se você deseja converter um datetime de python em segundos desde a época, deve fazê-lo explicitamente:
No Python 3.3 ou superior, você pode usar
timestamp()
:fonte
%s
, pois ele será localizado no relógio do sistema em que você está atualmente. Você só deve usar.timestamp()
para obter a hora Epoch / UNIX correta.%s
não funciona em sistemas Windows (ValueError: Invalid format string
)8
or9
Em vez desta expressão, para criar um carimbo de data / hora POSIX
dt
,Usa isto:
Eu recebo a resposta certa no seu exemplo usando o segundo método.
EDIT: Alguns acompanhamento ... Depois de alguns comentários (veja abaixo), eu estava curioso sobre a falta de apoio ou documentação para
%s
nostrftime
. Aqui está o que eu encontrei:Na fonte Python para
datetime
etime
, a stringSTRFTIME_FORMAT_CODES
nos diz:Então agora, se nós
man strftime
(em sistemas BSD como o Mac OS X), você encontrará suporte para%s
:De qualquer forma, é por isso que
%s
funciona nos sistemas que faz. Mas existem soluções melhores para o problema do OP (que levam em consideração os fusos horários). Veja a resposta aceita do @ abarnert aqui.fonte
strftime("%s")
na documentação, acabei de confirmar isso para funcionar no Mac e Linux. Obrigado.time.strftime()
e adatetime.strftime
delegação das plataformasstrftime(3)
funcionam para diretivas não suportadas.%s
pode falhar mesmo no Mac OS X, por exemplo, datetime.strftime ('% s') deve respeitar o tzinfo .%s
pois usará apenas a hora localizada do sistema em que está. Você deseja usar.timestamp()
se estiver tentando obter o registro de data e hora real do UNIX.Para trabalhar com fusos horários UTC:
fonte
Você perdeu as informações do fuso horário (já respondidas, concordadas)
arrow
pacote permite evitar essa tortura com as datas; Já está escrito, testado, publicado em pypi, com python cruzado (2.6 - 3.xx).Tudo que você precisa:
pip install arrow
(ou adicione às dependências)Solução para o seu caso
fonte
Se o seu objeto datetime representar a hora UTC, não use time.mktime, pois assume que a tupla está no fuso horário local. Em vez disso, use calendar.timegm:
fonte
Bem, ao converter o timestamp TO unix, o python está basicamente assumindo o UTC, mas, ao converter novamente, ele fornecerá uma data convertida para o fuso horário local.
Veja esta pergunta / resposta; Obter fuso horário usado por datetime.datetime.fromtimestamp ()
fonte
Se você desejar o carimbo de data / hora UTC:
time.mktime
apenas para dt local. O usocalendar.timegm
é seguro, mas dt deve a zona utc, portanto altere a zona para utc. Se dt no UTC apenas usecalendar.timegm
.fonte
fonte
Esta classe cobrirá suas necessidades, você pode passar a variável para ConvertUnixToDatetime e chamar a função em que deseja que ela funcione com base.
fonte