¿Cómo convertir datetime.time de UTC a una zona horaria diferente?

Tengo una variable que tiene el tiempo que es del tipo datetime.time en UTC, quería que se convirtiera a otra zona horaria.

podemos convertir las zonas horarias en la instancia de datetime.datetime como se muestra en este enlace SO: ¿Cómo convierto la hora local a UTC en Python? . No puedo averiguar cómo convertir las zonas horarias en instancias de datetime.time. No puedo usar astimezone porque datetime.time no tiene este método.

Por ejemplo:

>>> t = d.datetime.now().time() >>> t datetime.time(12, 56, 44, 398402) >>> 

Necesito ‘t’ en formato UTC.

Necesitas pytz . El caso de uso que usted describe se ilustra en sus ejemplos principales.

Me gustaría crear un objeto temporal de fecha, convertir el tz y extraer el tiempo de nuevo.

 import datetime def time_to_utc(t): dt = datetime.datetime.combine(datetime.date.today(), t) utc_dt = datetime_to_utc(dt) return utc_dt.time() t = datetime.datetime.now().time() utc_t = time_to_utc(t) 

donde, datetime_to_utc es cualquiera de las sugerencias en la pregunta vinculada .

Una forma sencilla de convertir desde / a la zona horaria UTC usando pytz :

 import datetime, pytz def time_to_utc(naive, timezone="Europe/Istanbul"): local = pytz.timezone(timezone) local_dt = local.localize(naive, is_dst=None) utc_dt = local_dt.astimezone(pytz.utc) return utc_dt def utc_to_time(naive, timezone="Europe/Istanbul"): return naive.replace(tzinfo=pytz.utc).astimezone(pytz.timezone(timezone)) # type(naive) """DateTime""" # type(timezone) """String""" 

Hay cuatro casos:

  1. La entrada datetime.time tiene tzinfo establecido (por ejemplo, OP menciones UTC)
    1. Salida como tiempo no ingenuo
    2. salida como tiempo ingenuo ( tzinfo no establecido)
  2. La entrada de datetime.time ha establecido tzinfo
    1. Salida como tiempo no ingenuo
    2. salida como tiempo ingenuo ( tzinfo no establecido)

La respuesta correcta debe utilizar la función datetime.datetime.timetz() porque datetime.time no puede construirse como una marca de tiempo no ingenua llamando directamente a localize() o astimezone() .

 from datetime import datetime, time import pytz def timetz_to_tz(t, tz_out): return datetime.combine(datetime.today(), t).astimezone(tz_out).timetz() def timetz_to_tz_naive(t, tz_out): return datetime.combine(datetime.today(), t).astimezone(tz_out).time() def time_to_tz(t, tz_out): return tz_out.localize(datetime.combine(datetime.today(), t)).timetz() def time_to_tz_naive(t, tz_in, tz_out): return tz_in.localize(datetime.combine(datetime.today(), t)).astimezone(tz_out).time() 

Ejemplo basado en el requisito de OP:

 t = time(12, 56, 44, 398402) time_to_tz(t, pytz.utc) # assigning tzinfo= directly would not work correctly with other timezones datetime.time(12, 56, 44, 398402, tzinfo=) 

En caso de que la marca de tiempo ingenua sea deseada:

 time_to_tz_naive(t, pytz.utc, pytz.timezone('Europe/Berlin')) datetime.time(14, 56, 44, 398402) 

Los casos en los que la instancia time () ya ha establecido tzinfo son más fáciles porque datetime.combine recoge el tzinfo del parámetro pasado, por lo que solo necesitamos convertirlo a tz_out .