it-swarm-es.tech

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

¿Cómo convierto un cadena en la hora local a una cadena en la hora UTC?

Estoy seguro de haber 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 tiempo 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 desde la hora local hasta la hora UTC.

264
Tom

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

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

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

time.gmtime
segundos desde la época -> Tuple en UTC

y

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

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

60
Tom

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")
236
John Millikin

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

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

Medir y almacenar siempre 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 la zona horaria!

NOTA- Si alguno de sus datos está 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 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'

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

117
monkut

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) . 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, ver 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, ver 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) → Fecha/hora de transmisión (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 ingenua (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, ver 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 pytz)
  • struct_time (UTC) → Aetime datetime (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, ver comentario de jfs)
  • Fecha/hora ingenua (UTC) → Fecha/hora actualizada:
    dt.replace(tzinfo=UTC)

Fuente: taaviburns.ca

32
akaihola
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 datetime.datetime object t, llame como:

local_to_utc(t.timetuple())
23
Chuck Callebs

Estoy teniendo buena suerte con dateutil (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 en fecha/hora local )

18
Yarin

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

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
12
Shu Wu
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'
7
Scipythonee

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")
5
user235042

Puedes hacerlo con:

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

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

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__.__== '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>)
2
Dantalion

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.

2
Anonymous fool

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

2
Yash

En python3:

pip install python-dateutil

from dateutil.parser import tz

mydt.astimezone(tz.gettz('UTC')).replace(tzinfo=None) 
0
spedy

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.

0
franksands