El tutorial o código que encontrarás en este post es la solución más fácil y efectiva que encontramos a tu duda o dilema.
Solución:
Si conoce su zona horaria de origen y la nueva zona horaria a la que desea convertirla, resulta muy sencillo:
-
Hacer una
pytz.timezone
objeto tanto para la zona horaria actual como para la nueva zona horaria, por ejemplopytz.timezone("US/Pacific")
. Si no conoce el nombre oficial de una zona horaria, puede encontrar una lista de todas las zonas horarias oficiales simplemente llamandopytz.all_timezones
-
Llamar
.localize()
utilizando el objeto pytz de la zona horaria actual con su fecha y hora / marca de tiempo como entrada para localizarlo en la zona horaria actual. p.ejcurrent_timezone.localize(timestamp)
-
Finalmente, llama
.astimezone()
en la fecha y hora / marca de tiempo recién localizada del paso 2 con el objeto pytz de la nueva zona horaria deseada como entrada, por ejemplolocalized_timestamp.astimezone(new_timezone)
.
¡Hecho!
Como ejemplo completo:
import datetime
import pytz
# a timestamp I'd like to convert
my_timestamp = datetime.datetime.now()
# create both timezone objects
old_timezone = pytz.timezone("US/Eastern")
new_timezone = pytz.timezone("US/Pacific")
# two-step process
localized_timestamp = old_timezone.localize(my_timestamp)
new_timezone_timestamp = localized_timestamp.astimezone(new_timezone)
# or alternatively, as an one-liner
new_timezone_timestamp = old_timezone.localize(my_timestamp).astimezone(new_timezone)
Bonificación: pero si todo lo que necesita es la hora actual en una zona horaria específica, puede pasar convenientemente esa zona horaria directamente a datetime.now () para obtener la hora actual directamente:
datetime.datetime.now(new_timezone)
Cuando se trata de necesitar conversiones de zonas horarias en general, recomiendo encarecidamente que se almacenen todas las marcas de tiempo en su base de datos en UTC, que no tiene transición al horario de verano (DST). Y como una buena práctica, siempre se debe optar por habilitar el soporte de zona horaria (¡incluso si sus usuarios están todos en una única zona horaria!). Esto le ayudará a evitar el problema de la transición DST que afecta tanto al software en la actualidad.
Más allá del horario de verano, el tiempo en el software generalmente puede ser bastante complicado. Para tener una idea de lo difícil que es lidiar con el tiempo en el software en general, aquí hay un recurso potencialmente esclarecedor: http://yourcalendricalfallacyis.com
Incluso una operación aparentemente simple como convertir una fecha y hora / marca de tiempo en una fecha puede volverse no obvia. Como señala esta útil documentación:
Una fecha y hora representa una punto en el tiempo. Es absoluto: no depende de nada. Por el contrario, una cita es una concepto de calendario. Es un período de tiempo cuyos límites dependen de la zona horaria en la que se considera la fecha. Como puede ver, estos dos conceptos son fundamentalmente diferentes.
Comprender esta diferencia es un key paso para evitar errores basados en el tiempo. Buena suerte.
¿Cómo se convierte la fecha y hora / marca de tiempo de una zona horaria a otra?
Hay dos pasos:
-
Cree objetos de fecha y hora conscientes a partir de la hora y la zona horaria del sistema por ejemplo, para obtener la hora actual del sistema en la zona horaria dada:
#!/usr/bin/env python from datetime import datetime import pytz server_timezone = pytz.timezone("US/Eastern") server_time = datetime.now(server_timezone) # you could pass *tz* directly
Nota:
datetime.now(server_timezone)
funciona incluso durante tiempos ambiguos, por ejemplo, durante las transiciones de DST mientrasserver_timezone.localize(datetime.now())
puede fallar (50% de probabilidad).Si está seguro de que su hora de entrada existe en la zona horaria del servidor y es única, puede pasar
is_dst=None
para afirmar que:server_time = server_timezone.localize(naive_time, is_dst=None)
Genera una excepción para tiempos inválidos.
Si es aceptable ignorar hasta un día error (aunque normalmente un error debido al horario de verano está alrededor una hora) entonces podrías dejaris_dst
parámetro:server_time = server_timezone.normalize(server_timezone.localize(naive_time))
.normalize()
se llama para ajustar tiempos no existentes (hora local en el espacio, durante las transiciones de “primavera hacia adelante”). Si las reglas de la zona horaria no han cambiado; su servidor no debería generar tiempos inexistentes. Consulte “¿Puedo establecer siempre is_dst = True?” -
Convierta un objeto de fecha y hora consciente en la zona horaria de destino
tz
:tz = pytz.timezone("US/Pacific") server_time_in_new_timezone = server_time.astimezone(tz)