datetime.datetime.utcnow()

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

我希望它包含tzinfo。


当前回答

在Python 3.2+中添加时区信息

import datetime

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

其他回答

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.

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以实现交叉兼容性。

这意味着它是无时区的,所以你不能在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. localalize (datetime.now())——当本地时间不明确时,它可能会在dst结束转换期间失败。

它还应该包括and 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

注意,对于Python 3.2起,datetime模块包含datetime.timezone。datetime.utcnow()的文档说:

可感知的当前UTC日期时间可以通过调用datetime.now(timezone.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)