为什么 datetime.tzinfo 实例需要一个日期时间来获取它自己的属性?

Why datetime.tzinfo instance needs a datetime to get its own attributes?

很长一段时间,我无法理解为什么tzinfo对象需要传递一个外部datetime来调用它的utcoffset()tzname()方法,这看起来非常独立于外部时间。

例如,我必须手动构造一个无用的日期时间对象来获取时区名称?

from datetime import datetime
from dateutil.tz import gettz
tz = gettz("UTC")
tz.tzname(datetime.now()) # UTC

查看datetime.py源码,执行timezone.tzname()

def tzname(self, dt):
    if isinstance(dt, datetime) or dt is None:
        if self._name is None:
            return self._name_from_offset(self._offset)
        return self._name
    raise TypeError("tzname() argument must be a datetime instance"
                    " or None")

我根本没看到 dt 被使用。

tzinfo 不应该知道它自己的名字,它与 UTC 的偏移量吗?时区的属性以何种方式依赖于外部时间点?也就是说,API为什么要这样设计?

因为时区的偏移量和名称在一年中的不同时间发生变化,甚至在历史上也是如此:

>>> tz
<DstTzInfo 'Europe/Berlin' LMT+0:53:00 STD>
>>> tz.tzname(datetime.now())
'CEST'
>>> tz.tzname(datetime(2018, 1, 1))
'CET'
>>> tz.tzname(datetime(1900, 1, 1))
'LMT'
>>> tz.utcoffset(datetime.now())
datetime.timedelta(0, 7200)
>>> tz.utcoffset(datetime(2018, 1, 1))
datetime.timedelta(0, 3600)

您在 UTC 中看不到这一点,但这是例外而不是规则。