datetime.datetime.utcnow()

为什么这个datetime没有任何时区信息,因为它是一个明确的UTC日期时间?

我希望它包含tzinfo。


当前回答

The behaviour of datetime.datetime.utcnow() returning UTC time as naive datetime object is obviously problematic and must be fixed. It can lead to unexpected result if your system local timezone is not UTC, since datetime library presume naive datetime object to represent system local time. For example, datetime.datetime.utcnow().timestaamp() gives timestamp of 4 hours ahead from correct value on my computer. Also, as of python 3.6, datetime.astimezone() can be called on naive datetime instances, but datetime.datetime.utcnow().astimezone(any_timezone) gives wrong result unless your system local timezone is UTC.

其他回答

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]

标准的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。获取当前时间作为感知datetime对象:

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时区信息。我怀疑这没有包括在内,因为本机datetime库默认为naive datetimes以实现交叉兼容性。

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

在Python 3.2+中添加时区信息

import datetime

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