Python: ¿Cómo convertir datetime / timestamp de una zona horaria a otra zona horaria?

Específicamente, dada la zona horaria de mi servidor (perspectiva de la hora del sistema) y una entrada de zona horaria, ¿cómo calculo la hora del sistema como si estuviera en esa nueva zona horaria (independientemente del horario de verano, etc.)?

import datetime current_time = datetime.datetime.now() #system time server_timezone = "US/Eastern" new_timezone = "US/Pacific" current_time_in_new_timezone = ??? 

Si conoce su zona horaria de origen y la nueva zona horaria a la que desea convertirla, primero use pytz.localize para manejar cualquier localización (por ejemplo, para el horario de verano, etc.), luego use pytz.timezone para crear objetos de la zona horaria, y finalmente use datetime.astimezone(timezone) para un cálculo fácil. Por ejemplo:

 import datetime import pytz # new import my_timestamp = datetime.datetime.now() # some timestamp old_timezone = pytz.timezone("US/Eastern") new_timezone = pytz.timezone("US/Pacific") # returns datetime in the new timezone my_timestamp_in_new_timezone = old_timezone.localize(my_timestamp).astimezone(new_timezone) 

Y, por supuesto, si todo lo que desea es la hora actual en una zona horaria específica, puede pasar esa zona horaria directamente a datetime.now () para obtener la marca de hora. Me gusta esto:

 datetime.datetime.now(new_timezone) 

Ahora, con todo lo dicho, recomiendo encarecidamente almacenar todas sus marcas de tiempo en UTC como un estándar del sistema, y ​​evitar todo el problema DST. Para un contexto sobre esto, consulte: http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/

Y para saber lo difícil que es lidiar con los cálculos de tiempo en general: http://yourcalendricalfallacyis.com

¿Cómo convertir datetime / timestamp de una zona horaria a otra zona horaria?

Hay dos pasos:

  1. Cree objetos de fecha y hora conscientes de la hora y zona horaria del sistema , por ejemplo, para obtener la hora actual del sistema en la zona horaria determinada:

     #!/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 DST, mientras que server_timezone.localize(datetime.now()) puede fallar (50% de probabilidad).

    Si está seguro de que su tiempo de entrada existe en la zona horaria del servidor y es único, puede pasar is_dst=None para afirmar que:

     server_time = server_timezone.localize(naive_time, is_dst=None) 

    Plantea una excepción para tiempos inválidos.
    Si es aceptable ignorar un error de hasta un día (aunque normalmente un error debido al horario de verano es de alrededor de una hora ), puede eliminar el parámetro is_dst :

     server_time = server_timezone.normalize(server_timezone.localize(naive_time)) 

    .normalize() se llama para ajustar los tiempos no existentes (hora local en el intervalo, durante las transiciones de “salto hacia adelante”). Si las reglas de la zona horaria no han cambiado; su servidor no debe generar tiempos no existentes Consulte “¿Puedo establecer siempre is_dst = True?”

  2. Convierta un objeto datetime consciente a la zona horaria objective tz :

     tz = pytz.timezone("US/Pacific") server_time_in_new_timezone = server_time.astimezone(tz)