Desde una zona horaria y una hora UTC, obtenga la diferencia en segundos frente a la hora local en ese momento.

Esto debería ser muy simple, pero no puedo entenderlo en Python. Quiero tener una función que tome dos argumentos, una hora UTC en segundos y un nombre de zona de información como ‘Europa / Viena’ y devuelva el desplazamiento en segundos desde la hora local y UTC para ese punto en el tiempo.

En C sería:

/* ... code to to set local time to the time zone I want to compare against, not shown here. Then call function below to get difference vs localtime. Hardly an ideal solution, but just to demonstrate what I want in a "lingua franca" (C): */ int get_diff_vs_localtime(const time_t original_utc_time) { struct tm* ts; ts = localtime(&original_utc_time); return mktime(ts) - original_utc_time; } 

Supongo que mi pregunta realmente se reduce a: “dada una zona horaria de Olson (ejemplo ‘Europa / Estocolmo’) y una hora UTC, ¿cuál es la hora local?

Asumiendo que “tiempo UTC en segundos” significa la marca de tiempo POSIX. Para convertirlo a tiempo de Estocolmo:

 from datetime import datetime import pytz tz = pytz.timezone('Europe/Stockholm') utc_dt = datetime.utcfromtimestamp(posix_timestamp).replace(tzinfo=pytz.utc) dt = tz.normalize(utc_dt.astimezone(tz)) print(dt.strftime('%Y-%m-%d %H:%M:%S %Z%z')) 

tz.normalize() es necesario si la zona horaria de origen es UTC (como en este caso).

Una alternativa más simple es usar el parámetro tz fromtimestamp() para convertir “segundos desde la época” a la hora local:

 from datetime import datetime import pytz tz = pytz.timezone('Europe/Stockholm') dt = datetime.fromtimestamp(posix_timestamp, tz) print(dt.strftime('%Y-%m-%d %H:%M:%S %Z%z')) 

Ambos ejemplos producen el mismo resultado.

Si la máquina local utiliza zonas horarias “correctas” para convertir la marca de hora POSIX recibida de una fuente externa a UTC, se podría usar una fórmula explícita:

 from datetime import datetime, timedelta import pytz utc_dt = datetime(1970, 1, 1, tzinfo=pytz.utc) + timedelta(seconds=posix_timestamp) 

La última fórmula también puede admitir un intervalo de fechas más amplio (menos problemas probables con fechas anteriores a 1970, después de 2038 o 3000 años).

Si la marca de tiempo proviene de la fuente “correcta” local, entonces deben usarse los dos primeros ejemplos (llaman ” time.gmtime()time.gmtime() ).

Podría usar pytz y datetime para hacer algo de la manera de:

 from datetime import datetime from pytz import timezone def get_diff(now, tzname): tz = timezone(tzname) utc = timezone('UTC') utc.localize(datetime.now()) delta = utc.localize(now) - tz.localize(now) return delta 

Que para el siguiente ejemplo …

 now = datetime.utcnow() print(now) tzname = 'Europe/Stockholm' delta = get_diff(now, tzname) print(delta) now_in_stockholm = now + delta print(now_in_stockholm) 

… salidas:

 2012-10-02 14:38:56.547475 2:00:00 2012-10-02 16:38:56.547475 

Supongo que mi pregunta realmente se reduce a: “dada una zona horaria de Olson (ejemplo ‘Europa / Estocolmo’) y una hora UTC, ¿cuál es la hora local?

Si entiendo tu problema correctamente:

 from pytz import timezone import datetime, time tz = timezone('Asia/Kuwait') utc_dt = datetime.datetime.utcfromtimestamp(time.time()) utc_dt + tz.utcoffset(utc_dt) >>> tz.utcoffset(utc_dt).seconds 10800 >>> tz  >>> utc_dt + tz.utcoffset(utc_dt) datetime.datetime(2012, 10, 2, 17, 13, 53, 504322) >>> utc_dt datetime.datetime(2012, 10, 2, 14, 13, 53, 504322) 

Esto es bastante antiguo, pero no pude encontrar una gran respuesta, así que esto es lo que se me ocurrió:

 from datetime import datetime local = datetime.now() utc = datetime.utcnow() int((local - utc).days * 86400 + round((local - utc).seconds, -1)) 

Devoluciones:

 -21600 

porque estoy (actualmente) 21600 segundos (6 horas) detrás de UTC.

Nota: la segunda fecha calculada (en este caso, UTC) debe redondearse, ya que existe una diferencia muy pequeña en el tiempo en cada cálculo.