Pregunta

¿Cómo convierto una fecha y hora? cadena en hora local a un 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:00 en mi zona horaria local (+10), me gustaría generar una cadena con el equivalente UTC tiempo: 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 la hora UTC.

¿Fue útil?

Solución 3

Gracias @rofly, la conversión completa de cadena a cadena 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 del time/calendar funciones:

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

Otros consejos

Primero, analice la cadena en un objeto ingenuo de fecha y hora.Este es un ejemplo de datetime.datetime sin información de zona horaria adjunta.Ver documentación para datetime.strptime para obtener información sobre cómo analizar la cadena de fecha.

Utilizar el pytz mó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() 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":

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í, puedes 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")

El módulo de fecha y hora utcnow() La función 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 el enlace mencionado anteriormente por Tom: http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/ dice:

UTC es una zona horaria sin tiempo de ahorro de día 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 hora local + información de zona horaria!

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

Desde Python 3.2 datetime.timezone está 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

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

Algunos métodos pierden fracciones de segundo y están marcados con (s).Una fórmula explícita como ts = (d - epoch) / unit se puede utilizar en su lugar (gracias jfs).

  • tiempo_estructura (UTC) → POSIX (s):
    calendar.timegm(struct_time)
  • Fecha y hora ingenua (local) → POSIX (s):
    calendar.timegm(stz.localize(dt, is_dst=None).utctimetuple())
    (excepción durante las transiciones de horario de verano, consulte el comentario de jfs)
  • Fecha y hora ingenua (UTC) → POSIX (s):
    calendar.timegm(dt.utctimetuple())
  • Consciente de fecha y hora → POSIX (s):
    calendar.timegm(dt.utctimetuple())
  • POSIX → estructura_hora (UTC, s):
    time.gmtime(t)
    (ver comentario de jfs)
  • Fecha y hora ingenua (local) → struct_time (UTC, s):
    stz.localize(dt, is_dst=None).utctimetuple()
    (excepción durante las transiciones de horario de verano, consulte el comentario de jfs)
  • Fecha y hora ingenua (UTC) → struct_time (UTC, s):
    dt.utctimetuple()
  • Consciente de fecha y hora → struct_time (UTC, s):
    dt.utctimetuple()
  • POSIX → Fecha y hora ingenua (local):
    datetime.fromtimestamp(t, None)
    (puede fallar en determinadas condiciones, consulte el comentario de jfs a continuación)
  • struct_time (UTC) → Fecha y hora ingenua (local, s):
    datetime.datetime(struct_time[:6], tzinfo=UTC).astimezone(tz).replace(tzinfo=None)
    (no puede representar segundos intercalares, ver comentario de jfs)
  • Fecha y hora ingenua (UTC) → Fecha y hora ingenua (local):
    dt.replace(tzinfo=UTC).astimezone(tz).replace(tzinfo=None)
  • Fecha y hora consciente → Fecha y hora ingenua (local):
    dt.astimezone(tz).replace(tzinfo=None)
  • POSIX → Fecha y hora ingenua (UTC):
    datetime.utcfromtimestamp(t)
  • struct_time (UTC) → Fecha y hora ingenua (UTC, s):
    datetime.datetime(*struct_time[:6])
    (no puede representar segundos intercalares, ver comentario de jfs)
  • Fecha y hora ingenua (local) → Fecha y hora ingenua (UTC):
    stz.localize(dt, is_dst=None).astimezone(UTC).replace(tzinfo=None)
    (excepción durante las transiciones de horario de verano, consulte el comentario de jfs)
  • Fecha y hora consciente → Fecha y hora ingenua (UTC):
    dt.astimezone(UTC).replace(tzinfo=None)
  • POSIX → Fecha y hora consciente:
    datetime.fromtimestamp(t, tz)
    (puede fallar en zonas horarias que no son de Pytz)
  • struct_time (UTC) → Fecha y hora conscientes (s):
    datetime.datetime(struct_time[:6], tzinfo=UTC).astimezone(tz)
    (no puede representar segundos intercalares, ver comentario de jfs)
  • Fecha y hora ingenua (local) → Fecha y hora consciente:
    stz.localize(dt, is_dst=None)
    (excepción durante las transiciones de horario de verano, consulte el comentario de jfs)
  • Fecha y hora ingenua (UTC) → Fecha y hora consciente:
    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

Uso de ejemplo de bd808:Si tu fuente es un datetime.datetime objeto t, llame como:

local_to_utc(t.timetuple())

estoy teniendo buena suerte con fechautil (que se recomienda ampliamente 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 a Convertir la cadena de fecha y hora UTC a fecha y hora local)

Un ejemplo más con pytz, pero incluye localize(), lo 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 prefieres 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 los segundos son None luego convierte la hora local a la hora UTC; de lo contrario, convierte la hora pasada a UTC.

Simple

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 elegante

Si quieres algo más sofisticado, puedes convertir esto en un 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

Para evitar el 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=<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>)

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 te hace la vida más fácil :)

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 bibliotecas integradas de Python y no requiere que ingreses tu 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)

Vuelvo a publicar 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 la mejor biblioteca

import pytz
utc = pytz.utc
yourdate = datetime.datetime.now()
yourdateutc = yourdate.astimezone(utc).replace(tzinfo=None)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top