datetime.datetime.utcnow()
为什么这个datetime
没有任何时区信息,因为它明确是UTC datetime
?
我希望这会包含tzinfo
。
答案 0 :(得分:167)
这意味着它是时区,因此您无法将其与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过渡期间失败。
答案 1 :(得分:96)
请注意,对于Python 3.2及更高版本,datetime
模块包含datetime.timezone
。 datetime.utcnow()
的文档说:
可以通过致电
datetime.now
(
timezone.utc
)
来获取当前的UTC日期时间。
所以你可以这样做:
>>> import datetime
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2014, 7, 10, 2, 43, 55, 230107, tzinfo=datetime.timezone.utc)
答案 2 :(得分:66)
标准Python库不包含任何tzinfo类(但see pep 431)。我只能猜测原因。就个人而言,我认为不包括UTC的tzinfo类是错误的,因为那个版本对于标准实现来说是没有争议的。
编辑虽然库中没有实现,但tzinfo
documentation中有一个例子。
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()
要使用它,要将当前时间作为有意识的日期时间对象:
from datetime import datetime
now = datetime.now(utc)
Python 3.2 +中有datetime.timezone.utc
:
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
答案 3 :(得分:19)
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时区信息。我怀疑这不包括在内,因为本机日期时间库默认为天真的日期时间以实现交叉兼容性。
答案 4 :(得分:9)
实际上,Python datetime API总是会返回不知道的日期时间对象, 这是非常不幸的。的确,只要你得到其中一个 对象,没有办法知道时区是什么,因此这些 对象本身非常“无用”。
唉,即使你可以使用utcnow()
,你仍然不会看到你所发现的时区信息。
建议:
始终使用感知
datetime
个对象,即带有时区信息。那 确保您可以直接比较它们(知道和不知道datetime
对象不具有可比性)并将它们正确地返回给用户。 利用 pytz 来获取时区对象。使用 ISO 8601 作为输入和 输出字符串格式。使用
datetime.datetime.isoformat()
返回 时间戳作为使用该格式格式化的字符串,其中包括 时区信息。如果需要解析包含ISO 8601格式的时间戳的字符串, 你可以依赖
iso8601
,它会返回正确的时间戳 时区信息。这使得时间戳可以直接比较。
答案 5 :(得分:3)
在Python 3.2 +
中添加timezone
信息
import datetime
>>> d = datetime.datetime.now(tz=datetime.timezone.utc)
>>> print(d.tzinfo)
'UTC+00:00'
答案 6 :(得分:0)
datetime.datetime.utcnow()
返回UTC时间作为朴素的datetime对象的行为显然是有问题的,必须解决。如果您的系统本地时区不是UTC,则可能导致意外结果,因为datetime库假定天真的datetime对象代表系统本地时间。例如,datetime.datetime.utcnow().timestaamp()
使时间戳比我的计算机上的正确值提前4个小时。另外,从python 3.6开始,datetime.astimezone()
可以在朴素的datetime实例上调用,但是datetime.datetime.utcnow().astimezone(any_timezone)
给出错误的结果,除非您的系统本地时区为UTC。
答案 7 :(得分:-6)
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]
答案 8 :(得分:-13)
UTC日期不需要任何时区信息,因为它们是UTC,根据定义,它们没有偏移量。