Python: Converte UTC time-tuple para timestamp UTC
Meu problema: eu preciso converter uma tupla de tempo UTC em um timestamp UTC. Mas tenho algumas confusões.
Primeiro um pouco de informação:
time.mktime(tuple)
: esta função sempre retorna o timestamp emlocal Tempo.
Esta é a função inversa do localtime (). Seu argumento é o struct_time ou full 9-tuple que expressa o tempo emhora local, não UTC.
calendar.timegm(tuple)
: isso retorna oTimestamp UTC da tupla de tempo fornecida
leva uma tupla de tempo, como retornado pela função gmtime () no módulo de tempo, e retorna o valor de registro de data e hora Unix correspondente. De fato,time.gmtime () e timegm () são inversos uns dos outros
Agora vamos fazer um teste:
>>> from datetime import datetime
>>> import time
>>> import calendar as cal
>>> utc_now = datetime.utcnow()
>>> now = datetime.now()
>>> utc_now
datetime.datetime(2013, 3, 16, 9, 17, 22, 489225)
>>> now
datetime.datetime(2013, 3, 16, 5, 17, 29, 736903)
>>> time.mktime(datetime.timetuple(utc_now)), time.mktime(datetime.timetuple(now))
(1363439842.0, 1363425449.0)
>>> cal.timegm(datetime.timetuple(utc_now)), cal.timegm(datetime.timetuple(now))
(1363425442, 1363411049)
Por que existem quatro valores diferentes? E qual é a certa quando eu quero converter uma UTC de tempo em um timestamp UTC?
UPDATTE
Acho que encontrei respostas para minhas confusões, então deixe-me explicar.
Primeiro, precisamos saber algo importante:
Existem dois tipos de objetos de data e hora: “ingênuo” e “consciente”.
Um objeto ciente tem conhecimento suficiente dos ajustes de tempo políticos e algorítmicos aplicáveis, como informações de fuso horário e de horário de verão, para se localizar em relação a outros objetos conscientes. Um objeto consciente é usado para representar um momento específico no tempo que não está aberto à interpretação [1].
Um objeto ingênuo não contém informações suficientes para se localizar de forma não ambígua em relação a outros objetos de data / hora.Se um objeto ingênuo representa o tempo universal coordenado (UTC), a hora local ou a hora em algum outro fuso horário é puramente até o programa, assim como depende do programa se um determinado número representa metros, milhas ou massa. Objetos ingênuos são fáceis de entender e de trabalhar, ao custo de ignorar alguns aspectos da realidade.
O que temos dedatetime.utcnow()
oudatetime.now()
são objetos "ingênuos". Isso significa que odatetime
O objeto que é retornado não diz nada sobre seu horário local ou horário UTC - ele representa apenas "algum tempo". Ele apenas encapsula informações de data e hora (ano, mês, dia, hora, minutos, segundos, etc.). É SUA responsabilidade associá-lo à noção de local ou UTC.
Portanto, lembre-se de que um objeto datetime ingênuo representa apenas "algum tempo". odatetime.now()
função retorna um "algum tempo" que é igual ao seu tempo atual, eodatetime.utcnow()
função retorna "algum tempo" que é a hora atual em Greenwich Inglaterra (que é o que é UTC).
O "algum tempo" é apenas um valor para data e hora. E note que em locais diferentes da Terra, o "tempo" ocorre em tempos diferentes. Por exemplo, se um valor "algum tempo" for 1 de janeiro, 10:30, será a hora atual em Greenwich Inglaterra cerca de 5 horas ANTES de se tornar a hora atual em Nova York.
Assim, podemos ver que há duas coisas: um valor "algum tempo" genérico e a noção de que "algum tempo" se torna tempo atual em locais diferentes em "tempos" diferentes. (sem trocadilho aqui, continue a ler)
Agora, vamos primeiro definir o que é "época". Sabemos que "algum tempo" é apenas um valor genérico de tempo. Então, a época é "algum tempo" que ocorreu em Greenwich, Inglaterra, onde os valores dos parâmetros são:January 1 1970, 00:00:00
.
Um "timestamp" é não. de segundos que se passaram desde a época. Isso significa que o timestamp foi0
quando o tempo foiJan 1, 1970, 00:00:00
em Greenwich, Inglaterra. Mas o timestamp foi de aprox. (5 * 60 * 60) quando o tempo foiJan 1, 1970, 00:00:00
Em Nova Iórque.
>>> tt = datetime.timetuple(datetime(1970, 1, 1, 0, 0, 0))
>>> cal.timegm(tt)
0
Assim, podemos ver que o mesmo valor "algum tempo" deJan 1, 1970, 00:00:00
tem timestamps diferentes quando mudamos de local. Portanto, quando você fala sobre timestamp, você precisa também dizer "em que localização" está o registro de data e hora relacionado a Eastward ou Westward, que está relacionado a Greenwich England. Esse local é expresso como "fuso horário".
Agora, cada sistema (computador) tem um fuso horário configurado e todos os registros de data e hora relacionados a esse fuso horário se tornam efetivamente "locais". O UTC é a referência global.
Então, digamos que você tenha umX
valor para "algum tempo" que converte para:
Y
timestamp no seu horário localZ
timestamp em UTCentão isso significa queY
não. de segundos terá que decorrer "algum tempo" para se tornar a hora atual em sua localização eZ
nenhum segundo terá que passar para que a hora atual em Greenwich Inglaterra se torne "algum tempo".
Agora, finalmente, vamos voltar para nossas funçõesmktime
etimegm
. Estes levam uma tupla de tempo, que é apenas outra representação para "algum tempo". Lembre-se que estamos passando um tempo ingênuo que não tem noção de local ou UTC.
DigamosX
é uma tupla de tempo representando um ingênuo "algum tempo". Então
mktime(X)
retornará o não. de segundos que terão que decorrer para que o seu horário local se torne "algum tempo" etimegm(X)
retornará o número de segundos que terão que ser gastos para tornar a hora atual de Greenwich Inglaterra igual a "algum tempo".No exemplo acima,now
eutc_now
representam ingênuo "algum tempo", e quando nós alimentamos esses valores de "algum tempo"mktime
etimegm
, eles simplesmente retornam o não. de segundos que tem que passar para os locais correspondentes (sua localização e Greenwich Inglaterra) para ter seu tempo atual ser que "algum tempo".
Finalmente, voltando ao meu problema: Eu preciso converter uma tupla de tempo UTC em um timestamp UTC.
Em primeiro lugar, não há conceito de "UTC time-tuple" - é apenas "algum tempo". Se eu precisar convertê-lo para UTC, eu simplesmente usotimegm
:
cal.timegm(datetime.timetuple(utc_now))
que me dará o timestamp para a hora UTC atual (ou seja, a atual "algum tempo" em Greenwich, Inglaterra).