¿Cómo convertir una cadena de hora local a UTC?

Resuelto Tom asked hace 16 años • 26 respuestas

¿Cómo convierto una cadena de fecha y hora en hora local en una cadena en hora UTC ?

Estoy seguro de haber hecho esto antes, pero no puedo encontrarlo y espero que SO me ayude (y a otros) a hacerlo en el futuro.

Aclaración : Por ejemplo, si tengo 2008-09-17 14:02:00en mi zona horaria local ( +10), me gustaría generar una cadena con la UTChora equivalente 2008-09-17 04:02:00:.

Además, desde http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/ , tenga en cuenta que, en general, esto no es posible ya que con el horario de verano y otros problemas no existe una conversión única de la hora local a Hora UTC.

Tom avatar Sep 17 '08 10:09 Tom
Aceptado

Primero, analice la cadena en un objeto ingenuo de fecha y hora. Esta es una instancia datetime.datetimesin información de zona horaria adjunta. Ver su documentación .

Utilice el pytzmódulo, que viene con una lista completa de zonas horarias + UTC. Descubra cuál es la zona horaria local, construya un objeto de zona horaria a partir de ella, manipúlelo y adjuntelo a la ingenua fecha y hora.

Finalmente, use datetime.astimezone()el método para convertir la fecha y hora a UTC.

Código fuente, utilizando la zona horaria local "America/Los_Angeles", para la cadena "2001-2-3 10:11:12":

from datetime import datetime   
import pytz

local = pytz.timezone("America/Los_Angeles")
naive = 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)

Desde allí, puede utilizar el strftime()método para formatear la fecha y hora UTC según sea necesario:

utc_dt.strftime("%Y-%m-%d %H:%M:%S")
John Millikin avatar Sep 17 '2008 04:09 John Millikin

NOTA : a partir de 2020 no debería utilizar .utcnow()o .utcfromtimestamp(xxx). Como probablemente haya pasado a Python3, debería utilizar objetos de fecha y hora que reconozcan la zona horaria.

>>> from datetime import timezone
>>> 
>>> # alternative to '.utcnow()'
>>> dt_now = datetime.datetime.now(datetime.timezone.utc)
>>>
>>> # alternative to '.utcfromtimestamp()'
>>> dt_ts = datetime.fromtimestamp(1571595618.0, tz=timezone.utc)

Para obtener más detalles, consulte: https://blog.ganssle.io/articles/2019/11/utcnow.html

respuesta original (de 2010):

La función utcnow() del módulo datetime se puede utilizar para obtener la hora UTC actual.

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

Como dice el enlace mencionado anteriormente por Tom: http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/ :

UTC es una zona horaria sin horario de verano y sigue siendo una zona horaria sin cambios de configuración en el pasado.

Mida y almacene siempre la hora en UTC .

Si necesita registrar dónde se tomó la hora, guárdelo por separado. ¡No almacene la información de hora local + zona horaria!

NOTA : si alguno de sus datos se encuentra en una región que usa DST, use pytzy consulte la respuesta de John Millikin.

Si desea obtener la hora UTC de una cadena determinada y tiene la suerte de estar en una región del mundo que no usa DST o tiene datos que solo se compensan con UTC sin aplicar DST:

--> utilizando la hora local como base para el valor de compensación:

>>> # 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'

--> O, desde un desplazamiento conocido, 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'

ACTUALIZAR:

Dado que Python 3.2 datetime.timezoneestá disponible. Puede generar un objeto de fecha y hora compatible con la zona horaria con el siguiente comando:

import datetime

timezone_aware_dt = datetime.datetime.now(datetime.timezone.utc)

Si está listo para realizar conversiones de zona horaria, lea esto:

https://medium.com/@eleroy/10-cosas-que-necesitas-saber-sobre-fecha-y-hora-en-python-with-datetime-pytz-dateutil-timedelta-309bfbafb3f7

monkut avatar Feb 01 '2010 07:02 monkut

Gracias @rofly, la conversión completa de cadena a cadena es la siguiente:

import time
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"))))

Mi resumen de las funciones time/ calendar:

time.strptime
cadena --> tupla (no se aplica zona horaria, por lo que coincide con la cadena)

time.mktime
Tupla de hora local --> segundos desde la época (siempre hora local)

time.gmtime
segundos desde época --> tupla en UTC

y

calendar.timegm
tupla en UTC --> segundos desde la época

time.localtime
segundos desde la época -> tupla en la zona horaria local

Tom avatar Sep 17 '2008 04:09 Tom