Quando si fa datetime.now(pytz_timezone)
falliscono?
Per quanto posso dire, non ci sono scenari in cui potrebbe fallire. datetime.now
richiama la funzione fromutc
sull'istanza tzinfo
passata nel parametro. Tutte le conversioni da UTC a ora locale non sono ambigue, quindi non ci sono opportunità di fallimento.
Inoltre, il codice originale non funziona nemmeno.
d = est.normalize(EST)
Ciò sembrerebbe passare una stringa come unico parametro normalize
, che è destinato a prendere un datetime
. Questo dà:
AttributeError: 'str' object has no attribute 'tzinfo'
Credo che lo scopo di scrivere:
d = est.normalize(d.astimezone(est))
Detto questo, non credo che la verbosità del loro codice aggiunge molto valore. Come avrete notato, è altrettanto facile fare questo in un unico passaggio:
d = datetime.now(est)
Guardando il cpython source code for datetime.now
, posso vedere che, quando è previsto un oggetto tzinfo
, si chiama il metodo fromutc
su tale oggetto.
if (self != NULL && tz != Py_None) {
/* Convert UTC to tzinfo's zone. */
PyObject *temp = self;
self = _PyObject_CallMethodId(tz, &PyId_fromutc, "O", self);
Py_DECREF(temp);
}
Poi, nella sorgente pytz, vedo che il metodo è implementato fromutc
diverso a seconda che la zona è pytz.UTC
, oppure un'istanza di StaticTzInfo
o DstTzInfo
. In tutti e tre i casi, la trasformazione dal valore UTC di input al fuso orario target non è ambigua.Ecco l'implementazione DstTzInfo
, che è il più complesso dei tre:
def fromutc(self, dt):
'''See datetime.tzinfo.fromutc'''
if (dt.tzinfo is not None
and getattr(dt.tzinfo, '_tzinfos', None) is not self._tzinfos):
raise ValueError('fromutc: dt.tzinfo is not self')
dt = dt.replace(tzinfo=None)
idx = max(0, bisect_right(self._utc_transition_times, dt) - 1)
inf = self._transition_info[idx]
return (dt + inf[0]).replace(tzinfo=self._tzinfos[inf])
Questo sembrerebbe trovare il passaggio dalla _utc_transition_times
del fuso orario, poi applicarlo alla restituita datetime
. Non ci sono ambiguità in questa direzione, quindi i risultati saranno equivalenti.
Vale anche la pena notare, in the datetime
docs si dice che datetime.now
è equivalente a chiamare:
tz.fromutc(datetime.utcnow().replace(tzinfo=tz))
Data la fonte di fromutc
in pytz ho mostrato in precedenza, non sono sicuro che questo è diverso non solo:
tz.fromutc(datetime.utcnow())
Ma in entrambi i casi, non credo che localize
e normalize
sono necessari.
Il suo obiettivo è dare un esempio sulla pagina principale del progetto di come usare 'Delorean' è più pulito che usare' datetime' e 'pytz'. È un cattivo esempio perché è un codice errato e può essere gestito meglio dal tuo esempio, ma il tuo esempio non raggiunge l'obiettivo originale. Forse proporre un nuovo esempio che mostri un caso in cui 'localize' e' normalize' siano effettivamente necessari e come sia più facilmente gestito con un 'Delorean'? – heenenee
Ho archiviato un [problema] (https://github.com/myusuf3/delorean/issues/70) con delorean, quindi hanno creato una [richiesta pull] (https://github.com/myusuf3/delorean/pull/ 71/files) che pulisce il primo esempio. (Hanno anche pulito l'esempio delorean.) –
@heenenee: la mia domanda riguarda 'datetime.now (tz)': se puoi sempre usarlo per restituire l'ora corrente in un determinato fuso orario invece di est.normalize (utc .localize (datetime.uctnow()). astimezone (est)) '. – jfs