¿Cómo convierto una cadena de fecha y hora en hora local en una cadena en hora UTC ?
Estoy seguro de que he hecho esto antes, pero no puedo encontrarlo y SO espero que me ayude (y a 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 el equivalente UTC
de tiempo: 2008-09-17 04:02:00
.
Además, en 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 hay una conversión única de la hora local a Hora UTC.
Respuestas:
Primero, analiza la cadena en un objeto ingenuo datetime. Esta es una instancia
datetime.datetime
sin información de zona horaria adjunta. Consulte la documentación paradatetime.strptime
obtener información sobre cómo analizar la cadena de fecha.Use el
pytz
módulo, que viene con una lista completa de zonas horarias + UTC. Averigua cuál es la zona horaria local, construye un objeto de zona horaria a partir de ella, y manipúlalo y adjúntalo a la fecha y hora ingenua.Finalmente, use el
datetime.astimezone()
método para convertir la fecha y hora a UTC.Código fuente, usando la zona horaria local "America / Los_Angeles", para la cadena "2001-2-3 10:11:12":
Desde allí, puede usar el
strftime()
método para formatear la fecha y hora UTC según sea necesario:fuente
tzlocal.get_localzone()
para obtener la zona horaria local comopytz
objetoLa función utcnow () del módulo datetime se puede usar para obtener la hora UTC actual.
Como dice el enlace mencionado anteriormente por Tom: http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/ dice:
NOTA - Si alguno de sus datos se encuentra en una región que usa DST, use
pytz
y eche un vistazo a la respuesta de John Millikin.Si desea obtener el tiempo UTC de una cadena determinada y tiene la suerte de estar en una región del mundo que no utiliza DST o tiene datos que solo se compensan desde UTC sin DST aplicado:
-> utilizando la hora local como base para el valor de compensación:
-> O, desde un desplazamiento conocido, usando datetime.timedelta ():
ACTUALIZAR:
Desde python 3.2
datetime.timezone
está disponible. Puede generar un objeto datetime con reconocimiento de zona horaria con el siguiente comando:Si estás listo para realizar conversiones de 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
fuente
tzinfo.utcoffset() must return a whole number of minutes
etc.Gracias @rofly, la conversión completa de cadena a cadena es la siguiente:
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 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
fuente
(always local time)
parece estar equivocado: la entrada a mktime () es hora local, la salida es segundos desde epoch (1970-01-01 00:00:00 +0000 (UTC)
) que no depende de la zona horaria.Aquí hay un resumen de las conversiones de tiempo comunes de Python.
Algunos métodos sueltan fracciones de segundos y están marcados con (s) . En su lugar,
ts = (d - epoch) / unit
se puede usar una fórmula explícita como (gracias jfs).calendar.timegm(struct_time)
calendar.timegm(stz.localize(dt, is_dst=None).utctimetuple())
(excepción durante las transiciones DST, ver comentario de jfs)
calendar.timegm(dt.utctimetuple())
calendar.timegm(dt.utctimetuple())
time.gmtime(t)
(ver comentario de jfs)
stz.localize(dt, is_dst=None).utctimetuple()
(excepción durante las transiciones DST, ver comentario de jfs)
dt.utctimetuple()
dt.utctimetuple()
datetime.fromtimestamp(t, None)
(puede fallar en ciertas condiciones, vea el comentario de jfs a continuación)
datetime.datetime(struct_time[:6], tzinfo=UTC).astimezone(tz).replace(tzinfo=None)
(no puede representar segundos intercalares, ver comentario de jfs)
dt.replace(tzinfo=UTC).astimezone(tz).replace(tzinfo=None)
dt.astimezone(tz).replace(tzinfo=None)
datetime.utcfromtimestamp(t)
datetime.datetime(*struct_time[:6])
(no puede representar segundos intercalares, ver comentario de jfs)
stz.localize(dt, is_dst=None).astimezone(UTC).replace(tzinfo=None)
(excepción durante las transiciones de horario de verano, ver comentario de jfs)
dt.astimezone(UTC).replace(tzinfo=None)
datetime.fromtimestamp(t, tz)
(puede fallar para zonas horarias que no son de Pytz)
datetime.datetime(struct_time[:6], tzinfo=UTC).astimezone(tz)
(no puede representar segundos bisiestos, ver comentario de jfs)
stz.localize(dt, is_dst=None)
(excepción durante las transiciones DST, ver comentario de jfs)
dt.replace(tzinfo=UTC)
Fuente: taaviburns.ca
fuente
fromtimestamp(t, None)
puede fallar si la zona horaria local tiene un desplazamiento utc diferente ent
y la biblioteca C no tiene acceso a la base de datos tz en la plataforma dada. Puede utilizartzlocal.get_localzone()
para proporcionar tzdata de forma portátil. (2)fromtimestamp(t, tz)
puede fallar para zonas horarias que no son de Pytz. (3)datetime(*struct_time[:6])
te estás perdiendo*
. (4)timegm()
,utctimetuple()
,struct_time
las soluciones basadas en caer fracciones de un segundo. Podría usar una fórmula explícita como: en suts = (d - epoch) / unit
lugar.stz.localize(dt, is_dst=None)
plantea una excepción para tiempos locales ambiguos o inexistentes, por ejemplo, durante las transiciones DST. Para evitar la excepción, use un resultadostz.normalize(stz.localize(dt))
que pueda arrojar resultados imprecisos. (6) datetime () no puede representar un segundo intercalar. Conviertastruct_time
primero a "segundos desde época" como solución alternativa. (7) atime.gmtime(t)
diferencia de lo quecalendar.timegm()
puede esperar entrada no POSIX si se utiliza la zona horaria "correcta". Utilice la fórmula explícita si la entrada es POSIX en su lugar:gmtime = lambda t: datetime(1970,1,1, tzinfo=utc) + timedelta(seconds=t)
<table>
etiquetas. Lo sentimos. Esto es intencional y por diseño. Si necesita una" tabla "rápida y sucia, use un<pre>
diseño ASCII". No creo que una tabla ASCII sea más legible que la lista anterior.Fuente: http://feihonghsu.blogspot.com/2008/02/converting-from-local-time-to-utc.html
Ejemplo de uso de bd808 : si su fuente es un
datetime.datetime
objetot
, llame como:fuente
t
, llame como: local_to_utc (t.timetuple ()).timetuple()
conjuntos de llamadastm_isdst
a-1
; hay un 50% de posibilidades de quemktime()
falle durante la transición al horario de verano.Estoy teniendo buena suerte con dateutil (que se recomienda ampliamente en SO para otras preguntas relacionadas):
(El código se derivó de esta respuesta para convertir la cadena de fecha y hora UTC a fecha y hora local )
fuente
dateutil
puede fallar para fechas pasadas si la zona horaria local tenía un desplazamiento utc diferente (no relacionado con las transiciones DST) en sistemas donde la implementación no utiliza una base de datos histórica de zonas horarias (especialmente Windows).pytz
+tzlocal
podría usarse en su lugar.Un ejemplo más con pytz, pero incluye localize (), que me salvó el día.
fuente
He tenido el mayor éxito con python-dateutil :
fuente
dateutil
puede fallar para fechas pasadasfuente
mktime(dt.timetuple())
puede fallar durante la transición DST . ExisteLocalTimezone
en los documentos (funciona para la definición de zona horaria más reciente pero puede fallar para fechas pasadas (no relacionadas con el horario de verano))si prefiere datetime.datetime:
fuente
mktime()
espera la hora local como entrada.fromtimestamp()
devuelve la hora local, no utc. Si lo soluciona, vea estos problemas adicionales (por ejemplodateutil
, la solución solo stdlib puede fallar)Sencillo
Lo hice así:
Implementación de lujo
Si quieres ponerte elegante, puedes convertir esto en un functor:
Resultado:
fuente
Puedes hacerlo con:
fuente
Qué tal si -
si son segundos
None
, convierte la hora local en hora UTC; de lo contrario, convierte la hora pasada en UTC.fuente
Para moverse por el horario de verano, etc.
Ninguna de las respuestas anteriores me ayudó particularmente. El siguiente código funciona para GMT.
fuente
Usando http://crsmithdev.com/arrow/
Esta biblioteca hace la vida fácil :)
fuente
Encontré la mejor respuesta en otra pregunta aquí . Solo usa bibliotecas integradas de Python y no requiere que ingrese su zona horaria local (un requisito en mi caso)
Estoy volviendo a publicar la respuesta aquí, ya que esta pregunta aparece en Google en lugar de la pregunta vinculada, dependiendo de las palabras clave de búsqueda.
fuente
Tengo este código en uno de mis proyectos:
fuente
En python3:
pip install python-dateutil
fuente
from dateutil import tz
Qué tal si -
si son segundos
None
, convierte la hora local en hora UTC; de lo contrario, convierte la hora pasada en UTC.fuente