¿Cómo convertir la cadena de tiempo local a UTC?

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

Estoy seguro de haberlo hecho antes, pero no puedo encontrarlo y, por lo tanto, espero que me ayude a mí (ya otros) a hacerlo en el futuro.

Aclaración : por ejemplo, si tengo 2008-09-17 14:02:00 en mi zona horaria local ( +10 ), me gustaría generar una cadena con la hora UTC 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 DST y otros problemas no hay una conversión única de la hora local a Hora UTC.

Primero, analice la cadena en un objeto de fecha y hora ingenuo. Esta es una instancia de datetime.datetime sin información de zona horaria adjunta. Consulte la documentación de datetime.strptime para obtener información sobre el análisis de la cadena de fecha.

Use el módulo pytz , que viene con una lista completa de zonas horarias + UTC. Averigüe cuál es la zona horaria local, construya un objeto de zona horaria a partir de ella, y manipúlelo y adjúntelo a la fecha y hora ingenua.

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

Código fuente, usando la zona horaria local “America / Los_Angeles”, para la cadena “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) 

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

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

La función utcnow () del módulo datetime se puede usar 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 aún una zona horaria sin cambios de configuración en el pasado.

Siempre mida y almacene el tiempo en UTC .

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

NOTA : si alguno de sus datos se encuentra en una región que usa horario de verano, use pytz y observe la respuesta de John Millikin.

Si desea obtener la hora UTC de una cadena dada y tiene la suerte de estar en una región del mundo que no usa DST, o si tiene datos que solo están compensados ​​de UTC sin DST aplicado:

-> usando 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, utilizando 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' 

Si estás listo para tomar conversiones de la zona horaria, lee esto:

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

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

 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 de time / calendar :

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

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

time.gmtime
segundos desde la é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

Aquí hay un resumen de las conversiones de tiempo de Python comunes.

Algunos métodos eliminan fracciones de segundos y están marcados con (s) . En su lugar, se puede usar una fórmula explícita como ts = (d - epoch) / unit (gracias jfs).

  • struct_time (UTC) → POSIX (s) :
    calendar.timegm(struct_time)
  • Fecha / hora ingenua (local) → POSIX (s) :
    calendar.timegm(stz.localize(dt, is_dst=None).utctimetuple())
    (excepción durante las transiciones DST, vea el comentario de jfs)
  • Fecha / hora ingenua (UTC) → POSIX (s) :
    calendar.timegm(dt.utctimetuple())
  • Aetime datetime → POSIX (s) :
    calendar.timegm(dt.utctimetuple())
  • POSIX → struct_time (UTC, s ):
    time.gmtime(t)
    (ver comentario de jfs)
  • Fecha / hora ingenua (local) → struct_time (UTC, s ):
    stz.localize(dt, is_dst=None).utctimetuple()
    (excepción durante las transiciones DST, vea el comentario de jfs)
  • Fecha / hora ingenua (UTC) → struct_time (UTC, s ):
    dt.utctimetuple()
  • Aware datetime → struct_time (UTC, s ):
    dt.utctimetuple()
  • POSIX → fecha / hora naïve (local):
    datetime.fromtimestamp(t, None)
    (puede fallar en ciertas condiciones, vea el comentario de jfs a continuación)
  • struct_time (UTC) → Sin fecha (local, s ):
    datetime.datetime(struct_time[:6], tzinfo=UTC).astimezone(tz).replace(tzinfo=None)
    (no puede representar segundos de salto, vea el comentario de jfs)
  • Fecha / hora naïve (UTC) → Fecha / hora naïve (local):
    dt.replace(tzinfo=UTC).astimezone(tz).replace(tzinfo=None)
  • Aetime datetime → Naïve datetime (local):
    dt.astimezone(tz).replace(tzinfo=None)
  • POSIX → fecha y hora ingenua (UTC):
    datetime.utcfromtimestamp(t)
  • struct_time (UTC) → hora de transmisión (UTC, s ):
    datetime.datetime(*struct_time[:6])
    (no puede representar segundos de salto, vea el comentario de jfs)
  • Fecha / hora naïve (local) → Fecha / hora naïve (UTC):
    stz.localize(dt, is_dst=None).astimezone(UTC).replace(tzinfo=None)
    (excepción durante las transiciones DST, vea el comentario de jfs)
  • Aetime datetime → Naïve datetime (UTC):
    dt.astimezone(UTC).replace(tzinfo=None)
  • POSIX → ATual datetime:
    datetime.fromtimestamp(t, tz)
    (puede fallar para zonas horarias que no sean de pytz)
  • struct_time (UTC) → Fecha (s) de fecha (s) :
    datetime.datetime(struct_time[:6], tzinfo=UTC).astimezone(tz)
    (no puede representar segundos de salto, vea el comentario de jfs)
  • Fecha / hora ingenua (local) → Fecha / hora actualizada:
    stz.localize(dt, is_dst=None)
    (excepción durante las transiciones DST, vea el comentario de jfs)
  • Fecha / hora ingenua (UTC) → Fecha / hora actualizada:
    dt.replace(tzinfo=UTC)

Fuente: taaviburns.ca

 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) 

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

Ejemplo de uso de bd808 : si su fuente es un objeto datetime.datetime t , llame como:

 local_to_utc(t.timetuple()) 

Estoy teniendo buena suerte con dateutil (que es ampliamente recomendado en SO para otras preguntas 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') 

(El código se derivó de esta respuesta para convertir la cadena de fecha y hora UTC en fecha y hora local )

Un ejemplo más con pytz, pero incluye localize (), que me salvó el día.

 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' 

He tenido el mayor éxito con 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 
 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' 

Si prefiere 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") 

Puedes hacerlo con:

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

Qué tal si –

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

si segundos es None entonces convierte la hora local a la hora UTC, o convierte la hora pasada a la hora UTC.

Para desplazarse en horario de verano, etc.

Ninguna de las respuestas anteriores me ayudó particularmente. El siguiente código funciona para GMT.

 def get_utc_from_local(date_time, local_tz=None): assert date_time.__class__.__name__ == '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=) winter_11_am = datetime(2011, 11, 11, 11) get_utc_from_local(winter_11_am) >>>datetime.datetime(2011, 11, 11, 11, 0, tzinfo=) 

Utilizando 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 hace la vida más fácil 🙂

Sencillo

Lo hice así:

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

Implementación de lujo

Si desea obtener fantasía, puede convertir esto en un funtor:

 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 

En python3:

pip install python-dateutil

 from dateutil.parser import tz mydt.astimezone(tz.gettz('UTC')).replace(tzinfo=None) 

Encontré la mejor respuesta en otra pregunta aquí . Solo utiliza las bibliotecas incorporadas de Python y no requiere que ingrese su zona horaria local (un requisito en mi 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) 

Estoy enviando la respuesta aquí ya que esta pregunta aparece en google en lugar de la pregunta vinculada según las palabras clave de búsqueda.

en este caso … pytz es mejor lib

 import pytz utc = pytz.utc yourdate = datetime.datetime.now() yourdateutc = yourdate.astimezone(utc).replace(tzinfo=None)