“datetime.now(pytz_timezone)”何时失败



delorean文档展示了使用datetime获取给定时区当前时间的方法:

from datetime import datetime
from pytz import timezone
EST = "US/Eastern"
UTC = "UTC"
d = datetime.utcnow()
utc = timezone(UTC)
est = timezone(EST)
d = utc.localize(d)
d = est.normalize(EST)

并将其与基于 Delorian 的代码进行比较:

from delorean import Delorean
EST = "US/Eastern"
d = Delorean(timezone=EST)

我认为datetime的例子应该写成:

from datetime import datetime
import pytz
eastern_timezone = pytz.timezone("US/Eastern")
d = datetime.now(eastern_timezone)

这样就更简洁了。

是否有最后一个代码示例失败而第一个代码示例继续工作的情况?


更新:当前示例:

from datetime import datetime
import pytz
d = datetime.utcnow()
d = pytz.utc.localize(d)
est = pytz.timezone('US/Eastern')
d = est.normalize(d)
return d

这还是太啰嗦了。

问题仍然存在:您是否需要通过 UTC 和 tz.normalize() 进行明确的往返,或者您可以使用datetime.now(tz)代替?

datetime.now(pytz_timezone)什么时候会失败?

据我所知,没有任何情况可能会失败。 datetime.now在参数中传递的tzinfo实例上调用 fromutc 函数。 从 UTC 到本地时间的所有转换都是明确的,因此没有失败的机会。

此外,原始代码甚至不起作用。

d = est.normalize(EST)

这似乎是将字符串作为唯一的参数传递给normalize,这是为了接受datetime。 这给出了:

AttributeError: 'str' object has no attribute 'tzinfo'

我相信他们的意思是写:

d = est.normalize(d.astimezone(est))

也就是说,我不认为他们代码的冗长增加了多少价值。 正如您所指出的,只需一步即可完成此操作同样简单:

d = datetime.now(est)

查看 datetime.now 的 cpython 源代码,我可以看到当提供 tzinfo 对象时,它会对该对象调用 fromutc 方法。

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);
}

然后,在 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文档中,它说datetime.now等同于调用:

tz.fromutc(datetime.utcnow().replace(tzinfo=tz))

鉴于我之前展示的 pytz 中fromutc的来源,我不确定这是否与仅:

tz.fromutc(datetime.utcnow())

但无论哪种情况,我认为localizenormalize都没有必要。

相关内容

  • 没有找到相关文章

最新更新