从datetime.time检索tzname

时间:2019-05-09 08:46:26

标签: python

我正在尝试将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

出什么问题了?

1 个答案:

答案 0 :(得分:1)

根据[Python 3.Docs]: datetime - time.tzname()

  

如果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 方法,但我认为这是一种解决方法。

code.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.