为什么datetime.datetime.utcnow()不包含时区信息?
datetime.datetime.utcnow()
为什么这个datetime
没有任何时区信息,因为它是显式的UTC datetime
?
我期望这将包含tzinfo
。
这意味着它是时区天真的,所以你不能用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库不包含任何tzinfo类(但请参阅pep 431 )。 我只能猜测原因。 就个人而言,我认为不包括UTC的tzinfo类是一个错误,因为那是一个没有争议的标准实现。
编辑:尽pipe库中没有实现,但在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()
要使用它,获取当前时间作为一个知道的date时间对象:
from datetime import datetime now = datetime.now(utc)
Python 3.2+中有datetime.timezone.utc
:
from datetime import datetime, timezone now = datetime.now(timezone.utc)
请注意,对于Python 3.2以后, datetime
模块包含datetime.timezone
。 datetime.utcnow()
的文档说:
可以通过调用
datetime.now
(
timezone.utc
)
来获得当前UTCdate时间。
所以你可以这样做:
>>> import datetime >>> datetime.datetime.now(datetime.timezone.utc) datetime.datetime(2014, 7, 10, 2, 43, 55, 230107, tzinfo=datetime.timezone.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时区信息。 我怀疑这不包括,因为本地date时间库默认为天真的date时间交叉兼容性。
Julien Danjou写了一篇很好的文章解释为什么你不应该处理时区 。 摘录:
事实上,Python的date时间API总是返回不知道的date时间对象,这是非常不幸的。 事实上,只要你得到这个对象中的一个,就没有办法知道时区是什么,因此这些对象本身是相当“无用”的。
唉,即使你可能使用utcnow()
,你仍然不会看到时区信息,因为你发现。
build议:
始终使用意识到的
datetime
对象,即与时区信息。 这可以确保你可以直接比较它们(知道和不知道的datetime
对象是不可比较的),并将它们正确地返回给用户。 利用pytz有时区对象。使用ISO 8601作为input和输出string格式。 使用
datetime.datetime.isoformat()
以时间戳的格式返回时间戳,格式包括时区信息。如果您需要parsing包含ISO 8601格式化时间戳的string,则可以使用
iso8601
,它会返回具有正确时区信息的时间戳。 这使得时间戳可以直接比较。
import datetime >>> d = datetime.datetime.now(tz=datetime.timezone.utc) >>> print(d.tzinfo) 'UTC+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]
UTCdate不需要任何时区信息,因为它们是UTC,根据定义,这意味着它们没有偏移量。