Nunca he tenido que convertir el tiempo hacia y desde UTC. Recientemente tuve una solicitud para que mi aplicación tuviera en cuenta la zona horaria, y me he estado ejecutando en círculos. Mucha información sobre la conversión de la hora local a UTC, que encontré bastante elemental (tal vez estoy haciendo eso mal también), pero no puedo encontrar ninguna información sobre cómo convertir fácilmente la hora UTC a la zona horaria de los usuarios finales.
En pocas palabras, y la aplicación de Android me envía datos (aplicación appengine) y dentro de esos datos hay una marca de tiempo. Para almacenar esa marca de tiempo a la hora utc que estoy usando:
datetime.utcfromtimestamp(timestamp)
Eso parece estar funcionando. Cuando mi aplicación almacena los datos, se almacena con 5 horas de anticipación (estoy EST -5)
Los datos se almacenan en BigTable de appengine y, cuando se recuperan, salen como una cadena de este modo:
"2011-01-21 02:37:21"
¿Cómo convierto esta cadena a DateTime en la zona horaria correcta de los usuarios?
Además, ¿cuál es el almacenamiento recomendado para la información de zona horaria de un usuario? (¿Cómo almacena típicamente información tz, es decir: "-5: 00" o "EST", etc., etc.?) Estoy seguro de que la respuesta a mi primera pregunta puede contener un parámetro que responda a la segunda.
Respuestas:
Si no desea proporcionar sus propios
tzinfo
objetos, consulte la biblioteca python-dateutil . Proporcionatzinfo
implementaciones en la parte superior de una base de datos zoneinfo (Olson) para que pueda consultar las reglas de zona horaria con un nombre algo canónico.Editar ejemplo ampliado para mostrar el
strptime
usoEditar 2 Uso de API fijo para mostrar un mejor método de punto de entrada
Editar 3 Métodos de detección automática incluidos para zonas horarias (Yarin)
fuente
dateutil.tz
y usartz.tzutc()
ytz.tzlocal()
como objetos de zona horaria que estaba buscando. Parece que la base de datos de zona horaria en mi sistema es buena (me registré/usr/share/zoneinfo
). No estoy seguro de lo que estaba pasando.tz
módulo es el punto de entrada correcto que se utilizará para esta biblioteca. He actualizado mi respuesta para reflejar esto. Eldateutil.zoneinfo
módulo que estaba mostrando anteriormente es utilizado internamente por eltz
módulo como una reserva si no puede ubicar la base de datos zonezone del sistema. Si mira dentro de la biblioteca, verá que hay un tarball DB de zoneinfo en el paquete que usa si no puede encontrar la base de datos de su sistema. Mi antiguo ejemplo estaba tratando de golpear esa base de datos directamente y supongo que tenía problemas para cargar esa base de datos privada (¿no está en la ruta de Python de alguna manera?)dateutil
, úsela en supytz
lugar .Aquí hay un método resistente que no depende de ninguna biblioteca externa:
Esto evita los problemas de tiempo en el ejemplo de DelboyJay. Y los problemas menores de tiempo en la enmienda de Erik van Oosten.
Como nota al pie interesante, el desfase de la zona horaria calculado anteriormente puede diferir de la siguiente expresión aparentemente equivalente, probablemente debido a cambios en la regla del horario de verano:
Actualización: este fragmento tiene la debilidad de utilizar el desplazamiento UTC de la hora actual, que puede diferir del desplazamiento UTC de la fecha y hora de entrada. Vea los comentarios sobre esta respuesta para otra solución.
Para conocer los diferentes tiempos, tome el tiempo de época del tiempo transcurrido. Esto es lo que hago:
fuente
pytz
db similar es imposible, ver PEP-431. Aunque puede escribir una solución solo stdlib que funcione en tales casos en sistemas que ya tienen una zona horaria histórica db, por ejemplo, Linux, OS X, vea mi respuesta .utc_datetime
momento.Consulte la documentación de fecha y hora en tzinfo objetos . Tiene que implementar las zonas horarias que desea soportar. Estos son ejemplos al final de la documentación.
Aquí hay un ejemplo simple:
Salida
fuente
replace
para configurar la zona horaria a GMT y hacer que la zona horaria sea "consciente", luego useastimezone
para convertir a otra zona horaria.Si desea obtener el resultado correcto incluso para la hora que corresponde a una hora local ambigua (p. Ej., Durante una transición de horario de verano) y / o el desplazamiento utc local es diferente en diferentes momentos de su zona
pytz
horaria local, entonces use zonas horarias:fuente
Esta respuesta debería ser útil si no desea utilizar otros módulos además
datetime
.datetime.utcfromtimestamp(timestamp)
devuelve undatetime
objeto ingenuo (no consciente). Los conscientes son conscientes de la zona horaria y los ingenuos no. Desea uno consciente si desea convertir entre zonas horarias (por ejemplo, entre UTC y hora local).Si no es usted quien crea la fecha para comenzar, pero aún puede crear un
datetime
objeto ingenuo en tiempo UTC, puede probar este código Python 3.x para convertirlo:Tenga cuidado de no asumir erróneamente que si su zona horaria es actualmente MDT, ese horario de verano no funciona con el código anterior, ya que imprime MST. Notará que si cambia el mes a agosto, imprimirá MDT.
Otra forma fácil de obtener un
datetime
objeto consciente (también en Python 3.x) es crearlo con una zona horaria especificada para comenzar. Aquí hay un ejemplo, usando UTC:Si usa Python 2.x, probablemente tendrá que subclasificar
datetime.tzinfo
y usar eso para ayudarlo a crear undatetime
objeto consciente , yadatetime.timezone
que no existe en Python 2.x.fuente
Si usa Django, puede usar el
timezone.localtime
método:fuente
Puedes usar flecha
Puedes alimentarte
arrow.get()
con cualquier cosa. marca de tiempo, cadena iso, etc.fuente
Tradicionalmente difiero esto a la interfaz de usuario: envíe las horas desde el backend como marcas de tiempo o algún otro formato de fecha y hora en UTC, luego dejo que el cliente descubra el desplazamiento de la zona horaria y procese estos datos en la zona horaria adecuada.
Para una aplicación web, esto es bastante fácil de hacer en JavaScript: puede calcular el desplazamiento de la zona horaria del navegador con bastante facilidad utilizando métodos incorporados y luego representar los datos del back-end correctamente.
fuente
Puede usar
calendar.timegm
para convertir su tiempo a segundos desde la época de Unix ytime.localtime
volver a convertir:Da
Fri Jan 21 05:37:21 2011
(porque estoy en la zona horaria UTC + 03: 00).fuente
por ejemplo, mi zona horaria es ' +08: 00 '. input utc = 2018-10-17T00: 00: 00.111Z , luego obtendré output = 2018-10-17T08: 00: 00 + 08: 00
fuente
De la respuesta aquí , puede usar el módulo de tiempo para convertir de utc a la hora local establecida en su computadora:
fuente
Aquí hay una versión rápida y sucia que utiliza la configuración del sistema local para resolver la diferencia horaria. NOTA: Esto no funcionará si necesita convertir a una zona horaria en la que su sistema actual no se está ejecutando. He probado esto con la configuración del Reino Unido en la zona horaria BST
fuente
datetime.fromtimestamp(ts)
: marca de tiempo posix (segundos flotantes) -> objeto de fecha y hora en hora local (funciona bien si el sistema operativo recuerda las compensaciones de utc pasadas para la zona horaria local, es decir, en Unix pero no en Windows para fechas anteriores)). De lo contrario, se podría usar pytz.offset = datetime.utcnow().replace(minute=0, second=0, microsecond=0) - datetime.now().replace(minute=0, second=0, microsecond=0)
Obtuve diferencias extrañas de microsegundos sin él.datetime.fromtimestamp(ts)
lugar de la respuesta?Consolidando la respuesta de franksands en un método conveniente.
fuente