2011-11-02 12 views
11

Attualmente sto lavorando al backend per un sistema di calendario che restituisce datazioni Python naive. Il modo in cui il front-end funziona è che l'utente crea vari eventi del calendario e il frontend restituisce la versione ingenua dell'evento che hanno creato (ad esempio, se l'utente seleziona il 5 ottobre 2020 dalle 3:00 alle 16:00, il frontend restituisce datetime.datetime (2020, 10, 5, 15, 0, 0) come inizio e datetime.datetime (2011, 10, 5, 16, 0, 0) come fineCome si converte un datetime ingenuo in datetime in DST-aware in Python?

Quello che devo fare è prendere l'ingenuo datetime e convertirlo in UTC per l'archiviazione in un database.Ogni utente del sistema ha già specificato la propria preferenza per il fuso orario, quindi l'ingenuo datetime è considerato dello stesso fuso orario della preferenza del fuso orario. essere memorizzati rispetto a UTC in modo che se gli utenti cambiano il loro fuso orario, gli eventi esistenti verranno ancora visualizzati all'ora corretta in cui sono stati pianificati.

Il frontend è fuori dal mio controllo, quindi non posso modificare i dati che sto ricevendo. Il design del database è anche fuori dal mio controllo, quindi non posso modificare quali dati vengono archiviati e come.

Qui è l'approccio approssimativo che ho preso finora:

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) 

Il problema che ho incontrato è legato alla Ora legale:

>>> 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 

Si noti che usando 'sostituire' imposta il fuso orario a PST invece di PDT indipendentemente dalla data, che gli dà un offset UTC di 8 ore anziché l'atteso DST di 7 ore di offset, quindi il tempo finisce per essere salvato in modo errato.

Quali opzioni sono disponibili per la conversione del datetime naive sulla PDT corretta (o un altro DST relativo al fuso orario) tzinfo?

(Inoltre, si noti che non tutti gli utenti vivono in un fuso orario che osserva l'ora legale, o possono vivere in un fuso orario che cambia in momenti diversi, quindi per fare una soluzione come una correzione timedelta prima di salvare, vorrei è necessario sapere se il fuso orario supporta l'ora legale e in quali date viene commutato).

+0

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

+0

possibile duplicato di [Come fare un fuso orario datetime ignaro aware in python] (http://stackoverflow.com/questions/7065164/how-to-make-an-unaware-datetime-timezone-aware-in-python) – Pureferret

risposta

18

funzione di Pytz localize può fare questo: 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

Grazie. Questo sembra essere quello che stavo cercando. – Jay

Problemi correlati