it-swarm-pt.tech

Como faço para converter a hora local para UTC em Python?

Como faço para converter um datetime string na hora local para um string na hora UTC?

Tenho certeza que já fiz isso antes, mas não consigo encontrá-lo e espero que SO me ajude (e a outros) a fazer isso no futuro.

Esclarecimento: Por exemplo, se eu tiver 2008-09-17 14:02:00 no meu fuso horário local (+10), gostaria de gerar uma string com o equivalente UTC time: 2008-09-17 04:02:00.

Além disso, em http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/ , observe que, em geral, isso não é possível, já que com o DST e outros problemas não há conversão única da hora local até a hora UTC.

248
Tom

Obrigado @rofly, a conversão completa de string para string é a seguinte:

time.strftime("%Y-%m-%d %H:%M:%S", 
              time.gmtime(time.mktime(time.strptime("2008-09-17 14:04:00", 
                                                    "%Y-%m-%d %H:%M:%S"))))

Meu resumo das funções time/calendar:

time.strptime
string -> Tuple (nenhum fuso horário aplicado, portanto, corresponde à string)

time.mktime
hora local Tuple -> segundos desde a época (sempre hora local)

time.gmtime
segundos desde a Epoch -> Tuple em UTC

calendar.timegm
Tupla em UTC -> segundos desde a época

time.localtime
segundos desde a Epoch -> Tuple no fuso horário local

60
Tom

Primeiro, analise a sequência em um objeto de data e hora ingênuo. Esta é uma instância de datetime.datetime sem informações de fuso horário anexadas. Veja a documentação para datetime.strptime para obter informações sobre a análise da string de data.

Use o pytz module, que vem com uma lista completa de fusos horários + UTC. Descubra qual é o fuso horário local, construa um objeto de fuso horário a partir dele e manipule-o e anexe-o ao datetime antigo.

Finalmente, use o método datetime.astimezone() para converter a data e hora em UTC.

Código-fonte, usando o fuso horário local "America/Los_Angeles", para a string "2001-2-3 10:11:12":

import pytz, datetime
local = pytz.timezone ("America/Los_Angeles")
naive = datetime.datetime.strptime ("2001-2-3 10:11:12", "%Y-%m-%d %H:%M:%S")
local_dt = local.localize(naive, is_dst=None)
utc_dt = local_dt.astimezone(pytz.utc)

A partir daí, você pode usar o método strftime() para formatar o datetime UTC conforme necessário:

utc_dt.strftime ("%Y-%m-%d %H:%M:%S")
221
John Millikin

A função utcnow () do módulo datetime pode ser usada para obter a hora UTC atual.

>>> import datetime
>>> utc_datetime = datetime.datetime.utcnow()
>>> utc_datetime.strftime("%Y-%m-%d %H:%M:%S")
'2010-02-01 06:59:19'

Como o link mencionado acima por Tom: http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/ diz:

O UTC é um fuso horário sem horário de verão e ainda um fuso horário Sem alterações de configuração no passado.

Sempre meça e armazene tempo no UTC

Se você precisar registrar onde o tempo foi tirado, armazene isso separadamente. Não armazene a hora local + informação de fuso horário!

NOTE - Se algum de seus dados estiver em uma região que usa DST, use pytz e dê uma olhada na resposta de John Millikin.

Se você deseja obter a hora UTC de uma determinada string e ter a sorte de estar em uma região do mundo que não usa DST ou possui dados que são apenas compensados ​​de UTC sem DST aplicado:

-> usando a hora local como base para o valor de compensação:

>>> # Obtain the UTC Offset for the current system:
>>> UTC_OFFSET_TIMEDELTA = datetime.datetime.utcnow() - datetime.datetime.now()
>>> local_datetime = datetime.datetime.strptime("2008-09-17 14:04:00", "%Y-%m-%d %H:%M:%S")
>>> result_utc_datetime = local_datetime + UTC_OFFSET_TIMEDELTA
>>> result_utc_datetime.strftime("%Y-%m-%d %H:%M:%S")
'2008-09-17 04:04:00'

-> Ou, a partir de um offset conhecido, usando datetime.timedelta ():

>>> UTC_OFFSET = 10
>>> result_utc_datetime = local_datetime - datetime.timedelta(hours=UTC_OFFSET)
>>> result_utc_datetime.strftime("%Y-%m-%d %H:%M:%S")
'2008-09-17 04:04:00'

Se você está pronto para aceitar conversões de fuso horário, leia isto:

https://medium.com/@eleroy/10-things-you-need-to-know-about-date-and-time-in-python-with-datetime-pytz-dateutil-timedelta-309bfbafb3f7

111
monkut

Aqui está um resumo das conversões de tempo comuns do Python.

Alguns métodos perdem frações de segundos e são marcados com (s). Uma fórmula explícita como ts = (d - Epoch) / unit pode ser usada no lugar (obrigado jfs).

  • struct_time (UTC) → POSIX (s):
    calendar.timegm(struct_time)
  • Data e hora Naïve (local) → POSIX (s):
    calendar.timegm(stz.localize(dt, is_dst=None).utctimetuple())
    (exceção durante as transições do horário de verão, veja o comentário do jfs)
  • Data e hora Naïve (UTC) → POSIX (s):
    calendar.timegm(dt.utctimetuple())
  • Data de validade ciente → POSIX (s):
    calendar.timegm(dt.utctimetuple())
  • POSIX → struct_time (UTC, s):
    time.gmtime(t)
    (veja o comentário do jfs)
  • Data e hora Naïve (local) → struct_time (UTC, s):
    stz.localize(dt, is_dst=None).utctimetuple()
    (exceção durante as transições do horário de verão, veja o comentário do jfs)
  • Data e hora Naïve (UTC) → struct_time (UTC, s):
    dt.utctimetuple()
  • Datetime com cuidado → struct_time (UTC, s):
    dt.utctimetuple()
  • POSIX → datetime inexistente (local):
    datetime.fromtimestamp(t, None)
    (pode falhar em certas condições, veja o comentário do jfs abaixo)
  • struct_time (UTC) → Data/hora naïve (local, s):
    datetime.datetime(struct_time[:6], tzinfo=UTC).astimezone(tz).replace(tzinfo=None)
    (não pode representar segundos bissextos, veja o comentário do jfs)
  • Data e hora Naïve (UTC) → Data e hora Naïve (local):
    dt.replace(tzinfo=UTC).astimezone(tz).replace(tzinfo=None)
  • Datetime ciente → Data e hora Naïve (local):
    dt.astimezone(tz).replace(tzinfo=None)
  • POSIX → datetime (UTC) Naïve:
    datetime.utcfromtimestamp(t)
  • struct_time (UTC) → datetime Naïve (UTC, s):
    datetime.datetime(*struct_time[:6])
    (não pode representar segundos bissextos, veja o comentário do jfs)
  • Data e hora Naïve (local) → Data e hora Naïve (UTC):
    stz.localize(dt, is_dst=None).astimezone(UTC).replace(tzinfo=None)
    (exceção durante as transições do horário de verão, veja o comentário do jfs)
  • Datetime ciente → Data e hora Naïve (UTC):
    dt.astimezone(UTC).replace(tzinfo=None)
  • POSIX → datetime ciente:
    datetime.fromtimestamp(t, tz)
    (pode falhar para fusos horários não pytz)
  • struct_time (UTC) → Data/hora de confirmação (s):
    datetime.datetime(struct_time[:6], tzinfo=UTC).astimezone(tz)
    (não pode representar segundos bissextos, veja o comentário do jfs)
  • Data e hora Naïve (local) → Data de Data Ciente:
    stz.localize(dt, is_dst=None)
    (exceção durante as transições do horário de verão, veja o comentário do jfs)
  • Data e hora Naïve (UTC) → Data de Data Ativa:
    dt.replace(tzinfo=UTC)

Fonte: taaviburns.ca

31
akaihola
def local_to_utc(t):
    secs = time.mktime(t)
    return time.gmtime(secs)

def utc_to_local(t):
    secs = calendar.timegm(t)
    return time.localtime(secs)

Fonte: http://feihonghsu.blogspot.com/2008/02/converting-from-local-time-to-utc.html

Exemplo de uso de bd808 : Se a sua fonte for um objeto datetime.datetimet, chame como:

local_to_utc(t.timetuple())
23
Chuck Callebs

Estou tendo boa sorte com dateutil (que é amplamente recomendado em SO para outras questões relacionadas):

from datetime import *
from dateutil import *
from dateutil.tz import *

# METHOD 1: Hardcode zones:
utc_zone = tz.gettz('UTC')
local_zone = tz.gettz('America/Chicago')
# METHOD 2: Auto-detect zones:
utc_zone = tz.tzutc()
local_zone = tz.tzlocal()

# Convert time string to datetime
local_time = datetime.strptime("2008-09-17 14:02:00", '%Y-%m-%d %H:%M:%S')

# Tell the datetime object that it's in local time zone since 
# datetime objects are 'naive' by default
local_time = local_time.replace(tzinfo=local_zone)
# Convert time to UTC
utc_time = local_time.astimezone(utc_zone)
# Generate UTC time string
utc_string = utc_time.strftime('%Y-%m-%d %H:%M:%S')

(O código foi derivado dessa resposta para Converter a cadeia de data e hora UTC em data/hora local )

18
Yarin

Mais um exemplo com pytz, mas inclui localize (), que salvou meu dia.

import pytz, datetime
utc = pytz.utc
fmt = '%Y-%m-%d %H:%M:%S'
amsterdam = pytz.timezone('Europe/Amsterdam')

dt = datetime.datetime.strptime("2012-04-06 10:00:00", fmt)
am_dt = amsterdam.localize(dt)
print am_dt.astimezone(utc).strftime(fmt)
'2012-04-06 08:00:00'
17
Paulius Sladkevičius

Eu tive mais sucesso com python-dateutil :

from dateutil import tz

def datetime_to_utc(date):
    """Returns date in UTC w/o tzinfo"""
    return date.astimezone(tz.gettz('UTC')).replace(tzinfo=None) if date.tzinfo else date
12
Shu Wu
import time

import datetime

def Local2UTC(LocalTime):

    EpochSecond = time.mktime(LocalTime.timetuple())
    utcTime = datetime.datetime.utcfromtimestamp(EpochSecond)

    return utcTime

>>> LocalTime = datetime.datetime.now()

>>> UTCTime = Local2UTC(LocalTime)

>>> LocalTime.ctime()

'Thu Feb  3 22:33:46 2011'

>>> UTCTime.ctime()

'Fri Feb  4 05:33:46 2011'
7
Scipythonee

se você preferir datetime.datetime:

dt = datetime.strptime("2008-09-17 14:04:00","%Y-%m-%d %H:%M:%S")
utc_struct_time = time.gmtime(time.mktime(dt.timetuple()))
utc_dt = datetime.fromtimestamp(time.mktime(utc_struct_time))
print dt.strftime("%Y-%m-%d %H:%M:%S")
5
user235042

Você pode fazer isso com:

>>> from time import strftime, gmtime, localtime
>>> strftime('%H:%M:%S', gmtime()) #UTC time
>>> strftime('%H:%M:%S', localtime()) # localtime
4
Cristian Salamea

Para evitar a economia de luz do dia, etc.

Nenhuma das respostas acima me ajudou particularmente. O código abaixo funciona para o GMT.

def get_utc_from_local(date_time, local_tz=None):
    assert date_time.__class__.__== 'datetime'
    if local_tz is None:
        local_tz = pytz.timezone(settings.TIME_ZONE) # Django eg, "Europe/London"
    local_time = local_tz.normalize(local_tz.localize(date_time))
    return local_time.astimezone(pytz.utc)

import pytz
from datetime import datetime

summer_11_am = datetime(2011, 7, 1, 11)
get_utc_from_local(summer_11_am)
>>>datetime.datetime(2011, 7, 1, 10, 0, tzinfo=<UTC>)

winter_11_am = datetime(2011, 11, 11, 11)
get_utc_from_local(winter_11_am)
>>>datetime.datetime(2011, 11, 11, 11, 0, tzinfo=<UTC>)
2
Dantalion

E se - 

time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(seconds))

se segundos for None, então a hora local será convertida para UTC.

2
Anonymous fool

Usando http://crsmithdev.com/arrow/

arrowObj = arrow.Arrow.strptime('2017-02-20 10:00:00', '%Y-%m-%d %H:%M:%S' , 'US/Eastern')

arrowObj.to('UTC') or arrowObj.to('local') 

Esta biblioteca facilita a vida :)

2
Yash

Simples

Eu fiz assim:

>>> utc_delta = datetime.utcnow()-datetime.now()
>>> utc_time = datetime(2008, 9, 17, 14, 2, 0) + utc_delta
>>> print(utc_time)
2008-09-17 19:01:59.999996

Implementação extravagante

Se você quiser ficar chique, você pode transformar isso em um functor:

class to_utc():
    utc_delta = datetime.utcnow() - datetime.now()

    def __call__(cls, t):
        return t + cls.utc_delta

Resultado: 

>>> utc_converter = to_utc()
>>> print(utc_converter(datetime(2008, 9, 17, 14, 2, 0)))
2008-09-17 19:01:59.999996
1
uclatommy

Em python 3:

pip install python-dateutil

from dateutil.parser import tz

mydt.astimezone(tz.gettz('UTC')).replace(tzinfo=None) 
0
spedy

Eu encontrei a melhor resposta em outra pergunta aqui . Ele usa somente bibliotecas internas de python e não requer que você insira seu fuso horário local (um requisito no meu caso) 

import time
import calendar

local_time = time.strptime("2018-12-13T09:32:00.000", "%Y-%m-%dT%H:%M:%S.%f")
local_seconds = time.mktime(local_time)
utc_time = time.gmtime(local_seconds)

Estou repostando a resposta aqui, pois essa pergunta aparece no google em vez da pergunta vinculada, dependendo das palavras-chave de pesquisa.

0
franksands