Ответ 1
Когда выполняется
datetime.now(pytz_timezone)
?
Насколько я могу судить, сценариев, где он может потерпеть неудачу, не существует. datetime.now
вызывает функцию fromutc
на экземпляре tzinfo
, переданном в параметре. Все конверсии с UTC по местному времени однозначны, поэтому нет возможности для отказа.
Кроме того, исходный код даже не работает.
d = est.normalize(EST)
Кажется, что строка передается как единственный параметр normalize
, который предназначен для принятия datetime
. Это дает:
AttributeError: 'str' object has no attribute 'tzinfo'
Я думаю, они хотели написать:
d = est.normalize(d.astimezone(est))
Тем не менее, я не думаю, что многословие их кода добавляет большую ценность. Как вы отметили, так же легко сделать это за один шаг:
d = datetime.now(est)
Глядя на исходный код cpython для datetime.now
, я вижу, что когда объект tzinfo
предоставляется, он вызывает fromutc
на этом объекте.
if (self != NULL && tz != Py_None) {
/* Convert UTC to tzinfo zone. */
PyObject *temp = self;
self = _PyObject_CallMethodId(tz, &PyId_fromutc, "O", self);
Py_DECREF(temp);
}
Затем в источнике pytz я вижу, что метод fromutc
реализуется по-разному в зависимости от того, является ли зона pytz.UTC
или экземпляром StaticTzInfo
или DstTzInfo
. Во всех трех случаях преобразование из входного значения UTC в целевой часовой пояс однозначно. Вот реализация DstTzInfo
, которая является более сложной из трех:
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])
Казалось бы, это найти переход от _utc_transition_times
часового пояса, а затем применить его к возвращенному datetime
. В этом направлении нет двусмысленностей, поэтому результаты будут эквивалентны.
Также стоит отметить, что в datetime
docs говорится, что datetime.now
эквивалентно вызову:
tz.fromutc(datetime.utcnow().replace(tzinfo=tz))
Учитывая источник fromutc
в pytz, который я показал ранее, я не уверен, что это не что иное, как просто:
tz.fromutc(datetime.utcnow())
Но в любом случае я не думаю, что localize
и normalize
необходимы.