`datetime.now(pytz_timezone)` 什么时候失败?
when does `datetime.now(pytz_timezone)` fail?
delorean
docs show this way to get the current time in a given timezone 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)
这样更简洁。
是否存在最后一个代码示例失败而第一个代码示例继续工作的情况?
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
还是太冗长了。
When does datetime.now(pytz_timezone)
fail?
据我所知,没有任何情况会失败。 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)
查看 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
的实例还是 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
。这个方向没有歧义,所以结果是等价的。
同样值得注意的是,在the datetime
docs中它说datetime.now
相当于调用:
tz.fromutc(datetime.utcnow().replace(tzinfo=tz))
鉴于我之前展示的 pytz 中 fromutc
的来源,我不确定这与以下内容有什么不同:
tz.fromutc(datetime.utcnow())
但无论哪种情况,我认为 localize
和 normalize
都没有必要。
delorean
docs show this way to get the current time in a given timezone 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)
这样更简洁。
是否存在最后一个代码示例失败而第一个代码示例继续工作的情况?
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
还是太冗长了。
When does
datetime.now(pytz_timezone)
fail?
据我所知,没有任何情况会失败。 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)
查看 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
的实例还是 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
。这个方向没有歧义,所以结果是等价的。
同样值得注意的是,在the datetime
docs中它说datetime.now
相当于调用:
tz.fromutc(datetime.utcnow().replace(tzinfo=tz))
鉴于我之前展示的 pytz 中 fromutc
的来源,我不确定这与以下内容有什么不同:
tz.fromutc(datetime.utcnow())
但无论哪种情况,我认为 localize
和 normalize
都没有必要。