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

时间:2015-08-07 21:20:18

标签: python datetime timezone pytz delorian

delorean docs以这种方式显示获取给定时区的当前时间 using 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)

I believe datetime示例应写为:

from datetime import datetime
import pytz

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

更简洁。

当最后一个代码示例失败而第一个代码示例继续工作时,是否存在任何情况?

更新: the current example:

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

仍然过于冗长。

问题仍然存在:do you need the explicit round-trip via utc and tz.normalize() or can you use datetime.now(tz) instead?

1 个答案:

答案 0 :(得分:11)

  

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 source code for datetime.now,我可以看到,当提供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的实例,还是{{1} }。在所有三种情况下,从输入UTC值到目标时区的转换是明确的。这是DstTzInfo实现,这是三个中更复杂的实现:

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。这个方向没有含糊之处,所以结果是等价的。

另外值得注意的是,在the datetime docs中它表示datetime等同于调用:

datetime.now

鉴于我之前展示的pytz tz.fromutc(datetime.utcnow().replace(tzinfo=tz)) 的来源,我不确定这是否与以下不同:

fromutc

但无论如何,我认为不需要tz.fromutc(datetime.utcnow()) localize