2011-11-02 9 views
11

Actualmente estoy trabajando en el back-end de un sistema de calendario que devuelve las fechas de inicio de Python. La forma en que funciona la interfaz es que el usuario crea varios eventos de calendario, y el frontend devuelve la versión ingenua del evento que crearon (por ejemplo, si el usuario selecciona el 5 de octubre de 2020 de 3:00 pm a 4:00 pm, el frontend regresa datetime.datetime (2020, 10, 5, 15, 0, 0) como el inicio y datetime.datetime (2011, 10, 5, 16, 0, 0) como el final.¿Cómo se convierte una fecha de inicio ingenua a la fecha de inicio de sesión con DST en Python?

Lo que tengo que hacer es para tomar el tiempo de programación ingenuo y convertirlo en UTC para el almacenamiento en una base de datos. Cada usuario del sistema ya ha especificado su preferencia de zona horaria, por lo que se considera que la fecha y hora naive son de la misma zona horaria que su preferencia de zona horaria. se almacenará en relación con UTC de modo que si los usuarios cambian su zona horaria, los eventos existentes seguirán apareciendo en el momento correcto en que los programaron.

El frontend está fuera de mi control, así que no puedo cambiar los datos que estoy recibiendo. El diseño de la base de datos también está fuera de mi control, por lo que no puedo cambiar qué datos se almacenan y cómo.

Aquí es el enfoque aproximada que he tomado hasta ahora:

import pytz 
def convert_to_UTC(naive_datetime, user_tz_preference): 
    user_datetime = naive_datetime.replace(tzinfo=user_tz_preference) 
    utc_datetime = user_datetime.astimezone(pytz.utc) 

El problema que encontré se relaciona con el horario de verano:

>>> from datetime import datetime 
>>> import pytz 
>>> user_tz_preference = pytz.timezone('US/Pacific') 
>>> naive_datetime = datetime(2011, 10, 26, 12, 0, 0) 
>>> user_datetime = naive_datetime.replace(tzinfo=user_tz_preference) 
>>> user_datetime 
datetime.datetime(2011, 10, 26, 12, 0, tzinfo=<DstTzInfo 'US/Pacific' PST-1 day, 16:00:00 STD>) 
>>> received_utc = user_datetime.astimezone(pytz.utc) 
>>> received_utc 
datetime.datetime(2011, 10, 26, 20, 0, tzinfo=<UTC>) 
>>> expected_utc = datetime(2011, 10, 26, 19, 0, tzinfo=pytz.utc) 
>>> expected_utc == received_utc 
False 

en cuenta que el uso de 'reemplazar' establece la zona horaria a PST en lugar de a PDT independientemente de la fecha, lo que le da un desplazamiento UTC de 8 horas en lugar del desplazamiento de DST esperado de 7 horas, por lo que el tiempo termina siendo guardado incorrectamente.

¿Qué opciones tengo para convertir el datetime ingenuo al PDT correcto (u otro DST relativo a la zona horaria) tzinfo?

(Además, tenga en cuenta que no todos los usuarios viven en una zona horaria que observa DST, o pueden vivir en una zona horaria que cambia en diferentes momentos, por lo que para hacer una solución como una corrección timedelta antes necesita saber si la zona horaria admite DST y en qué fechas cambia).

+0

http://www.enricozini.org/2009/debian/using-python-datetime/ –

+0

posible duplicado de [Cómo hacer una fecha y hora zona horaria desconocen consciente en python] (http://stackoverflow.com/questions/7065164/how-to-make-an-unaware-datetime-timezone-aware-in-python) – Pureferret

Respuesta

18

función de Pytz localize puede hacer esto: http://pytz.sourceforge.net/#localized-times-and-date-arithmetic

from datetime import datetime 
import pytz  

tz = pytz.timezone('US/Pacific') 
naive_dt = datetime(2020, 10, 5, 15, 0, 0) 
utc_dt = tz.localize(naive_dt, is_dst=None).astimezone(pytz.utc) 
# -> 2020-10-05 22:00:00+00:00 
+0

Gracias. Esto parece ser lo que estaba buscando. – Jay

Cuestiones relacionadas