首页 > 解决方案 > 从 datetime.time 中检索 tzname

问题描述

我正在尝试将 datetime.time 的 tzname 检查为

In [93]: t = datetime.time(6, 15, 30, 999999, dateutil.tz.gettz("UTC"))                                                       
In [94]: t                                                                                                                    
Out[94]: datetime.time(6, 15, 30, 999999, tzinfo=tzfile('/usr/share/zoneinfo/UTC'))
In [95]: t.tzname()  
#It return None

然而,

In [96]: t = datetime.time(6, 15, 30, 999999, dateutil.tz.tzutc())                                                            
In [97]: t.tzname()                                                                                                           
Out[97]: 'UTC'

尝试过

In [99]: t = datetime.time(6, 15, 30, 999999, dateutil.tz.gettz("America/New_York"))                                          
In [100]: t                                                                                                                   
Out[100]: datetime.time(6, 15, 30, 999999, tzinfo=tzfile('/usr/share/zoneinfo/America/New_York'))
In [101]: t.tzname()                                                                                                          
In [102]:    #return None

In [134]: !ls /usr/share/zoneinfo/UTC                                                                                         
/usr/share/zoneinfo/UTC

有什么问题?

标签: python

解决方案


根据[Python 3.Docs]:日期时间-时间。名称()

如果tzinfoNone,则返回None,否则返回self.tzinfo.tzname(None),或者如果后者不返回None或字符串对象则引发异常。

更详细地查看问题:

>>> import datetime
>>> import dateutil.tz
>>>
>>> tz0 = dateutil.tz.tzutc()
>>> tz1 = dateutil.tz.gettz("UTC")
>>> tz2 = dateutil.tz.gettz("America/New_York")
>>>
>>> tz0, tz1, tz2
(tzutc(), tzfile('/usr/share/zoneinfo/UTC'), tzfile('/usr/share/zoneinfo/America/New_York'))
>>>
>>> type(tz0), type(tz1), type(tz2)  # Notice the differences
(<class 'dateutil.tz.tz.tzutc'>, <class 'dateutil.tz.tz.tzfile'>, <class 'dateutil.tz.tz.tzfile'>)
>>> isinstance(tz0, datetime.tzinfo), isinstance(tz1, datetime.tzinfo), isinstance(tz2, datetime.tzinfo)
(True, True, True)
>>>
>>> tz0.tzname(None), tz1.tzname(None), tz2.tzname(None)
('UTC', None, None)

因此,显然对于tzfile对象,tzname不返回时区字符串,这是有充分理由的,因为这样的文件包含所有时区历史(可能随着时间而改变的部分),还有它的替代品和更多信息这可能会随日期而变化。

作为替代方案,您可以扩展datetime.time并覆盖其tzname方法,但我认为这是一种解决方法。

代码.py

#!/usr/bin/env python3

import sys
import datetime
import dateutil.tz


class time_tzfile(datetime.time):
    def tzname(self):
        if isinstance(self.tzinfo, dateutil.tz.tzfile):
            return getattr(getattr(self.tzinfo, "_ttinfo_std", None), "abbr", None)
        return super().tzname()


def main():
    t = time_tzfile(6, 15, 30, 999999, dateutil.tz.tzutc())
    print("{:}\n  Type: {:}\n  Name: {:s}".format(t.tzinfo, type(t.tzinfo), t.tzname()))
    t = time_tzfile(6, 15, 30, 999999, dateutil.tz.gettz("UTC"))
    print("{:}\n  Type: {:}\n  Name: {:s}".format(t.tzinfo, type(t.tzinfo), t.tzname()))
    t = time_tzfile(6, 15, 30, 999999, dateutil.tz.gettz("America/New_York"))
    print("{:}\n  Type: {:}\n  Name: {:s}".format(t.tzinfo, type(t.tzinfo), t.tzname()))


if __name__ == "__main__":
    print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
    main()
    print("\nDone.")

输出

[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q056055568]> python3 code.py
Python 3.5.2 (default, Nov 12 2018, 13:43:14)
[GCC 5.4.0 20160609] on linux

tzutc()
  Type: <class 'dateutil.tz.tz.tzutc'>
  Name: UTC
tzfile('/usr/share/zoneinfo/UTC')
  Type: <class 'dateutil.tz.tz.tzfile'>
  Name: UTC
tzfile('/usr/share/zoneinfo/America/New_York')
  Type: <class 'dateutil.tz.tz.tzfile'>
  Name: EST

Done.

推荐阅读