datetime.datetime.utcnow()
为什么这个
datetime
没有任何时区信息,因为它明确是UTCdatetime
?
我希望这会包含
tzinfo
。
datetime
模块包含 datetime.timezone
。 datetime.utcnow()
的文档说:
datetime.now
(
timezone.utc
获得已知的当前 UTC 日期时间。)
因此,
datetime.utcnow()
不会设置tzinfo
来指示它是UTC,但datetime.now(datetime.timezone.utc)
确实会返回UTC时间和tzinfo
设置。
所以你可以这样做:
>>> import datetime
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2014, 7, 10, 2, 43, 55, 230107, tzinfo=datetime.timezone.utc)
datetime.UTC
,相当于datetime.timezone.utc
。所以你也可以做datetime.datetime.now(datetime.UTC)
。
这意味着它是时区天真的,所以你不能将它与
datetime.astimezone
一起使用
你可以给它一个这样的时区
import pytz # 3rd party: $ pip install pytz
u = datetime.utcnow()
u = u.replace(tzinfo=pytz.utc) #NOTE: it works only with a fixed utc offset
现在您可以更改时区
print(u.astimezone(pytz.timezone("America/New_York")))
要获取给定时区的当前时间,您可以直接将 tzinfo 传递给
datetime.now()
:
#!/usr/bin/env python
from datetime import datetime
import pytz # $ pip install pytz
print(datetime.now(pytz.timezone("America/New_York")))
它适用于任何时区,包括遵守夏令时 (DST) 的时区,即,它适用于在不同时间可能具有不同 utc 偏移量的时区(非固定 utc 偏移量)。不要使用
tz.localize(datetime.now())
- 当本地时间不明确时,它可能会在 DST 结束过渡期间失败。
标准 Python 库直到 Python 3.2 才包含任何 tzinfo 类。我只能猜测原因。就我个人而言,我认为不包含 UTC 的 tzinfo 类是一个错误,因为该类没有争议,足以有一个标准实现。虽然库中没有实现,但在
tzinfo
文档中给出了一个示例。
from datetime import timedelta, tzinfo
ZERO = timedelta(0)
# A UTC class.
class UTC(tzinfo):
"""UTC"""
def utcoffset(self, dt):
return ZERO
def tzname(self, dt):
return "UTC"
def dst(self, dt):
return ZERO
utc = UTC()
一旦拥有 UTC
tzinfo
对象,您仍然无法将其与 utcnow
一起使用。要将当前时间作为感知日期时间对象获取:
from datetime import datetime
now = datetime.now(utc)
在 Python 3.2 中,他们终于在库中放入了 UTC
tzinfo
类:
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
在 Python 3.9 中,他们为所有其他时区创建了
tzinfo
类。有关所有详细信息,请参阅PEP 615 — 标准库中对 IANA 时区数据库的支持。
pytz
模块是一个选项,还有另一个python-dateutil
,虽然也是第三方软件包,但可能已经可用,具体取决于您的其他依赖项和操作系统。
我只是想将此方法纳入参考 - 如果您已经安装了
python-dateutil
用于其他目的,您可以使用它的 tzinfo
而不是与 pytz
重复
import datetime
import dateutil.tz
# Get the UTC time with datetime.now:
utcdt = datetime.datetime.now(dateutil.tz.tzutc())
# Get the UTC time with datetime.utcnow:
utcdt = datetime.datetime.utcnow()
utcdt = utcdt.replace(tzinfo=dateutil.tz.tzutc())
# For fun- get the local time
localdt = datetime.datetime.now(dateutil.tz.tzlocal())
我倾向于同意对
utcnow
的调用应包含 UTC 时区信息。我怀疑这不包括在内,因为本机日期时间库默认为天真的日期时间以实现交叉兼容性。
在Python 3.2+中添加
timezone
信息
import datetime
>>> d = datetime.datetime.now(tz=datetime.timezone.utc)
>>> print(d.tzinfo)
'UTC+00:00'
Julien Danjou 写了一篇很好的文章,解释了为什么你永远不应该处理时区。摘录:
确实,Python datetime API 总是返回不知道的 datetime 对象, 这是非常不幸的。事实上,一旦你得到其中之一 对象,无法知道时区是什么,因此这些 对象本身非常“无用”。
唉,即使您可以使用
utcnow()
,您仍然不会看到时区信息,正如您发现的那样。
建议:
始终使用感知的
对象,即带有时区信息的对象。那 确保您可以直接比较它们(有意识和无意识datetime
对象不具有可比性)并将它们正确返回给用户。 利用 pytz 来获取时区对象。datetime
使用 ISO 8601 作为输入并 输出字符串格式。使用
返回 时间戳为使用该格式格式化的字符串,其中包括 时区信息。datetime.datetime.isoformat()
如果您需要解析包含 ISO 8601 格式时间戳的字符串, 您可以信赖
,它会返回正确的时间戳 时区信息。这使得时间戳可以直接比较。iso8601
datetime.datetime.utcnow()
将 UTC 时间返回为原始日期时间对象的行为显然是有问题的,必须修复。如果您的系统本地时区不是 UTC,则可能会导致意外结果,因为日期时间库假定原始日期时间对象来表示系统本地时间。例如,
datetime.datetime.utcnow().timestaamp()
给出的时间戳比我计算机上的正确值提前 4 小时。另外,从 python 3.6 开始,可以在原始日期时间实例上调用
datetime.astimezone()
,但是
datetime.datetime.utcnow().astimezone(any_timezone)
会给出错误的结果,除非您的系统本地时区是 UTC。
now()
。相关问题。 所以在此之前,
now()
优于
today()
和
utcnow()
。
from datetime import datetime, timezone
utc = timezone.utc
date = datetime.now(utc)
print(date) # 2022-04-06 05:40:13.025347+00:00
from datetime import datetime
from dateutil.relativedelta import relativedelta
d = datetime.now()
date = datetime.isoformat(d).split('.')[0]
d_month = datetime.today() + relativedelta(months=1)
next_month = datetime.isoformat(d_month).split('.')[0]