为什么 datetime.datetime.utcnow() 不包含时区信息?

问题描述 投票:0回答:10
datetime.datetime.utcnow()

为什么这个

datetime
没有任何时区信息,因为它明确是UTC
datetime

我希望这会包含

tzinfo

python datetime timezone utc
10个回答
339
投票

请注意,对于 Python 3.2 及以上版本,

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)

从Python 3.11开始,还存在

datetime.UTC
,相当于
datetime.timezone.utc
。所以你也可以做
datetime.datetime.now(datetime.UTC)


247
投票

这意味着它是时区天真的,所以你不能将它与

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 结束过渡期间失败。


85
投票

标准 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 时区数据库的支持


21
投票

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 时区信息。我怀疑这不包括在内,因为本机日期时间库默认为天真的日期时间以实现交叉兼容性。


16
投票

在Python 3.2+中添加

timezone
信息

import datetime

>>> d = datetime.datetime.now(tz=datetime.timezone.utc)
>>> print(d.tzinfo)
'UTC+00:00'

10
投票

Julien Danjou 写了一篇很好的文章,解释了为什么你永远不应该处理时区。摘录:

确实,Python datetime API 总是返回不知道的 datetime 对象, 这是非常不幸的。事实上,一旦你得到其中之一 对象,无法知道时区是什么,因此这些 对象本身非常“无用”。

唉,即使您可以使用

utcnow()
,您仍然不会看到时区信息,正如您发现的那样。

建议:

  • 始终使用感知的

    datetime
    对象,即带有时区信息的对象。那 确保您可以直接比较它们(有意识和无意识
    datetime
    对象不具有可比性)并将它们正确返回给用户。 利用 pytz 来获取时区对象。

  • 使用 ISO 8601 作为输入并 输出字符串格式。使用

    datetime.datetime.isoformat()
    返回 时间戳为使用该格式格式化的字符串,其中包括 时区信息。

  • 如果您需要解析包含 ISO 8601 格式时间戳的字符串, 您可以信赖

    iso8601
    ,它会返回正确的时间戳 时区信息。这使得时间戳可以直接比较。


4
投票

datetime.datetime.utcnow()

 将 UTC 时间返回为原始日期时间对象的行为显然是有问题的,必须修复。如果您的系统本地时区不是 UTC,则可能会导致意外结果,因为日期时间库假定原始日期时间对象来表示系统本地时间。例如,
datetime.datetime.utcnow().timestaamp()
 给出的时间戳比我计算机上的正确值提前 4 小时。另外,从 python 3.6 开始,可以在原始日期时间实例上调用 
datetime.astimezone()
,但是 
datetime.datetime.utcnow().astimezone(any_timezone)
 会给出错误的结果,除非您的系统本地时区是 UTC。


3
投票
它还应该包括 和

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
    

-7
投票
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]
    

-16
投票
UTC 日期不需要任何时区信息,因为它们是 UTC,根据定义,这意味着它们没有偏移量。

© www.soinside.com 2019 - 2024. All rights reserved.