如何在Python中获得“时区感知”的datetime.today()值?
我想从当前的日期时间中减去一个日期值,以计算某件事情发生了多久。但是它给我报错:
TypeError: can't subtract offset-naive and offset-aware datetimes
从 datetime.datetime.today()
返回的值似乎没有“时区信息”,而我其他的日期值是有时区的。我该怎么做才能让 datetime.datetime.today()
返回一个带有时区信息的值呢?
理想的情况是它能自动识别时区。
现在,它给我的时间是本地时间,恰好是太平洋标准时间(PST),也就是UTC - 8小时。最糟糕的情况是,我能否手动把一个时区值输入到 datetime
对象中,并把它设置为UTC-8呢?
19 个回答
在 Python 3.9 及以上版本中:使用 zoneinfo
来处理 IANA 时区数据库:
在 Python 3.9 或更高版本中,你可以通过标准库来指定特定的时区,使用 zoneinfo
,像这样:
>>> import datetime
>>> from zoneinfo import ZoneInfo
>>> datetime.datetime.now(ZoneInfo("America/Los_Angeles"))
datetime.datetime(2020, 11, 27, 6, 34, 34, 74823, tzinfo=zoneinfo.ZoneInfo(key='America/Los_Angeles'))
zoneinfo
的时区数据库来自操作系统。如果你的操作系统没有 IANA 的时区数据库(比如 Windows),那么它会从一个叫 tzdata
的第三方包中获取这些信息,如果这个包可用的话。
在 Python 3.2 或更高版本中:
如果你需要指定 UTC 作为时区,标准库在 Python 3.2 或更高版本中提供了支持:
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2020, 11, 27, 14, 34, 34, 74823, tzinfo=datetime.timezone.utc)
你还可以使用 astimezone
来获取包含本地时间偏移的日期时间:
>>> datetime.datetime.now(datetime.timezone.utc).astimezone()
datetime.datetime(2020, 11, 27, 15, 34, 34, 74823, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600), 'CET'))
在 Python 3.6 或更高版本中,你可以把最后一行简化为:
>>> datetime.datetime.now().astimezone()
datetime.datetime(2020, 11, 27, 15, 34, 34, 74823, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600), 'CET'))
如果你想要一个只使用标准库,并且在 Python 2 和 Python 3 中都能工作的解决方案,可以查看 jfs 的回答。
获取当前时间,按照特定的时区:
import datetime
import pytz
my_date = datetime.datetime.now(pytz.timezone('US/Pacific'))
记得先安装 pytz
这个库。
在标准库中,没有跨平台的方法可以创建带时区的时间,除非你自己写一个时区类。补充:Python 3.9 引入了 zoneinfo
,这个功能现在可以在标准库中找到。
在Windows上,有 win32timezone.utcnow()
,但这属于pywin32库。我更推荐使用 pytz库,它有一个不断更新的大部分时区的数据库。
处理本地时区可能会非常棘手(可以查看下面的“进一步阅读”链接),所以你可能更想在整个应用程序中使用UTC,特别是在进行像计算两个时间点之间的差异这样的算术操作时。
你可以这样获取当前的日期和时间:
import pytz
from datetime import datetime
datetime.utcnow().replace(tzinfo=pytz.utc)
要注意的是,datetime.today()
和 datetime.now()
返回的是 本地 时间,而不是UTC时间,所以对它们使用 .replace(tzinfo=pytz.utc)
是不正确的。
还有一种更简洁的方法:
datetime.now(pytz.utc)
这个方法稍微短一些,但效果是一样的。
进一步阅读/观看为什么在很多情况下更喜欢使用UTC:
- pytz文档
- 每个开发者都应该知道的时间知识 – 针对许多实际使用案例的开发提示
- 时间和时区的问题 - Computerphile – 关于处理时区复杂性的有趣且发人深省的解释(视频)