1
| datetime.datetime.utcnow() |
为什么这个datetime没有任何时区信息,因为它明确是UTC datetime?
我希望这会包含tzinfo。
这意味着它是时区的天真,所以你不能用datetime.astimezone
你可以给它一个像这样的时区
1 2 3 4
| 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 |
现在你可以改变时区了
1
| print(u.astimezone(pytz.timezone("America/New_York"))) |
要获取给定时区的当前时间,可以直接将tzinfo传递给datetime.now():
1 2 3 4 5
| #!/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转换结束时失败。
-
但是没有充分的理由让它成为时区 - 它被指定为UTC。为什么需要搜索第三方库以使其正常工作?
-
我认为它可能是许可证,因此pytz不能包含在stdlib中
-
我同意;对我而言,'时代'完全没用。关于将pytz添加到stdlib的python列表的讨论;问题不是许可,而是时区数据经常更新的事实(Python本身不可能)。此外,pytz没有以预期的方式实现tzinfo接口,因此如果您尝试使用astimezone中的某些城市时区,则可能会出错。因此,datetime不仅没有本机时区,而且tzinfo唯一广泛可用的实现不符合所谓的标准。
-
@bobince为什么pytz和标准的datetime库不适合你呢? Python核心和pytz作为独立项目发展,降低了核心团队的后勤复杂性。是的,降低Python核心团队的复杂性会增加所有需要处理时区的Python用户的复杂性,但我相信他们做出这个决定是有充分理由的。规则"标准库没有tzinfo实例......"很棒,因为它很简单,为什么在这里例外?
-
怎么样只是u=datetime.now(pytz.utc)
-
@bobince标准库中缺少tzinfo肯定是个问题,但我不知道如何编写自己的代码作为解决方案比使用pytz库更容易,更快或更好,而pytz库是事实上的标准。Python世界。
-
我在一些项目中使用datetime / pytz(例如与Django交互的地方),但我发现它非常不方便。你总是会得到naï ve时间,UTC时间,本地时间,本地DST时间和其他服务器本地时间(例如DB)的混合。结果是混乱和错误。尝试将根本不同的模型(抽象日历点,绝对通用时刻和两者的组合)划分为相同的数据类型最终是错误的。我更喜欢只处理数据的时间戳,结合区域格式化/解析。
-
对于DST时区,tzinfo=不适用于pytz,请参阅此答案。
-
@bain:不要使用tz.localize(datetime.now());请改用datetime.now(tz)。
-
@ J.F这总是正确的吗? pytz"这个库与用于tzinfo实现的文档Python API不同;如果要创建本地wallclock时间,则需要使用本文档中记录的localize()方法。" - 文档没有说清楚何时可以安全地忽略该规则,也许它对datetime.now(?)总是安全的,但通常将pytz时区传递给日期时间是有风险的,例如datetime(2015, 1, 1, tzinfo=pytz.timezone('Europe/Paris'))
-
@bain:now(tz)总是正确的。我们这里没有讨论任何其他事情。
-
如果我不得不猜测为什么utcnow()不包含tzinfo,那可能是因为闰秒。换句话说,即使UTC也可能会发生变化。如果utcnow()包含一个tzinfo,那么肯定会有naï ve程序员没有意识到即使是utc tzinfo也需要不时更新,然后他们会遇到与时间相关的错误,并且仍然会划伤他们的头。
-
@JF pytz的作者说now(tz)并不总是正确的:'even"datetime.now(pytz.timezone('Australia / Melbourne'))"如果你不幸和DST过渡,可以给你一个小时的时间戳在该声明正在进行时发生了。
-
@bain:它只是证明即使是pytz作者也可能是错的。我见过代码。即使在DST转换期间,内部调用tz.fromutc的now(tz)也会起作用(因为utc中没有DST转换)。如果你认为我错了;提供具体的例子(日期,时区,python,pytz版本)
-
很长一段时间后,从最初的答案,但一个相对安全的本地化方式内置到pytz:pytz.utc.localize(datetime.utcnow())。我发现这也包含了DST变化而没有问题。
请注意,对于Python 3.2及更高版本,datetime模块包含datetime.timezone。 datetime.utcnow()的文档说:
An aware current UTC datetime can be obtained by calling datetime.now(timezone.utc).
所以你可以这样做:
1 2 3
| >>> import datetime
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2014, 7, 10, 2, 43, 55, 230107, tzinfo=datetime.timezone.utc) |
-
哪个更喜欢? datetime.now(timezone.utc)或datetime.utcnow(timezone.utc)?
-
datetime.utcnow()不带任何参数。所以它必须是datetime.now(timezone.utc)。
-
datetime.now()将返回机器时间,但datetime.utcnow()将返回实际的UTC时间。
-
@Babu:datetime.utcnow()未设置tzinfo以指示它是UTC。但datetime.now(datetime.timezone.utc)确实以tzinfo设置返回UTC时间。
-
@CraigMcQueen因此,如果我们在now构造函数中传递tz对象,它将返回该时区的时间?好!谢谢你指出。
-
我认为现在这是正确的解决方案,当它已经显式UTC时,不需要添加外部依赖项来指定时区元数据
标准Python库不包含任何tzinfo类(但请参阅pep 431)。我只能猜测原因。就个人而言,我认为不包括UTC的tzinfo类是错误的,因为那个没有足够的争议,有一个标准的实现。
编辑:虽然库中没有实现,但在tzinfo文档中有一个例子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| 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() |
要使用它,要将当前时间作为识别日期时间对象:
1 2 3
| from datetime import datetime
now = datetime.now(utc) |
Python 3.2+中有datetime.timezone.utc:
1 2 3
| from datetime import datetime, timezone
now = datetime.now(timezone.utc) |
-
去看看为什么首先没有提供这个类的原因(更重要的是,用于utcnow()创建的datetime对象)...
-
时区对象timezone.utc最终已添加到Python 3.2中。为了向后兼容,utcnow()仍然返回一个无时区的时间对象,但您可以通过调用now(timezone.utc)来获得所需的内容。
-
@rgove,这就是错误的纠正,这对于Python 3来说应该是公平的游戏。他们不应该担心向后兼容性。我在过去几天内阅读了另一个例子 - struct模块将自动从Unicode转换为字节串,最终的决定是破坏与早期Python 3版本的兼容性,以防止未来的错误决定。
-
我傻眼了,Python的tzinfo文档包含了实现它的代码示例,但它们并没有在datetime本身中包含该功能! docs.python.org/2/library/datetime.html#datetime.tzinfo.fromutc
-
此外,此处显示的示例UTC类几乎完全是pytz模块的实现所包含的内容。它增加了一些有用的方法。
-
@LS yes,pytz是一个很好的资源。当我编辑我的答案以放入示例代码时,其他人已经建议它,我不想窃取他们的雷声。
pytz模块是一个选项,还有另一个python-dateutil,虽然也是第三方软件包,但可能已经可用,具体取决于您的其他依赖项和操作系统。
我只想包含这种方法以供参考 - 如果您已经为其他目的安装了python-dateutil,则可以使用其tzinfo而不是与pytz重复
1 2 3 4 5 6 7 8 9 10 11 12
| 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时区信息。我怀疑这不包括在内,因为本机日期时间库默认为天真的日期时间以实现交叉兼容性。
-
NameError:未定义名称"dt"
-
我正在使用datetime.datetime.utcfromtimestamp()调用,需要添加tzinfo,第二个解决方案适用于我:utcdt = datetime.datetime.utcfromtimestamp(1234567890).replace(dateutil.tz.tzutc())
-
注意:与datetime.now(pytz_tz)不同,它始终有效;在DST转换期间,datetime.now(dateutil.tz.tzlocal())可能会失败。 PEP 495 - 当地时间消歧可能会改善未来的情况。
-
@IanLee:您可以使用utc_dt = datetime.fromtimestamp(1234567890, dateutil.tz.tzutc())(注意:带有非固定utc偏移量的dateutil(例如dateutil.tz.tzlocal())可能会失败,请改用基于pytz的解决方案)。
-
由于我的程序已经为dateutil.parser导入dateutil,我最喜欢这个解决方案。它很简单:utcCurrentTime = datetime.datetime.now(tz=dateutil.tz.tzutc())。中提琴!
-
谢谢,@ IanLee。仍然困扰我的部分是一个名为utcfromtimestamp的方法,它将POSIX时间戳作为参数,根据定义,它仍然生成一个naï ve日期时间。这对我来说似乎是一种明显的疏忽。
Julien Danjou写了一篇很好的文章,解释了为什么你永远不应该处理时区。摘录:
Indeed, Python datetime API always returns unaware datetime objects,
which is very unfortunate. Indeed, as soon as you get one of this
object, there is no way to know what the timezone is, therefore these
objects are pretty"useless" on their own.
唉,即使你可以使用utcnow(),你仍然不会看到你所发现的时区信息。
建议:
-
Always use aware datetime objects, i.e. with timezone information. That
makes sure you can compare them directly (aware and unaware datetime
objects are not comparable) and will return them correctly to users.
Leverage pytz to have timezone objects.
-
Use ISO 8601 as the input and
output string format. Use datetime.datetime.isoformat() to return
timestamps as string formatted using that format, which includes the
timezone information.
-
If you need to parse strings containing ISO 8601 formatted timestamps,
you can rely on iso8601, which returns timestamps with correct
timezone information. This makes timestamps directly comparable.
-
这是一个有点误导性的建议。经验法则是,永远不要处理时区。始终存储和传输tz unware utc对象(纪元对象)。时区应仅在UI中表示时计算
-
听起来它已经很好地与朱利安的想法相匹配了。他的哪些具体建议(如上所述)具有误导性?
在Python 3.2+中添加timezone信息
1 2 3 4 5
| import datetime
>>> d = datetime.datetime.now(tz=datetime.timezone.utc)
>>> print(d.tzinfo)
'UTC+00:00' |
-
AttributeError: 'module' object has no attribute 'timezone' Python 2.7.13(默认,2017年1月19日,14:48:08)
-
是的,这是Python3代码
1 2 3 4 5 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] |
UTC日期不需要任何时区信息,因为它们是UTC,根据定义,它们没有偏移量。
-
据docs.python.org/library/datetime.html所述,没有tzinfo的日期时间是未指定时区的日期时间。这里指定了时区,因此逻辑上它应该存在。没有相关时区的日期/时间与明确的UTC时间之间存在很大差异。 (理想情况下,它们应该是不同类型的IMO,但这是另一回事...)
-
@JonSkeet我认为你错过了Ignacio的观点,即UTC不是时区。令人惊讶的是,当我输入此答案时,这个答案有-9分...
-
@CS:那么伊格纳西奥从来没有说过......虽然严格来说UTC并不是一个时区,但它通常被视为一个让生活变得相当简单的东西(包括Python,例如pytz.utc)。请注意,与UTC的偏移量未知的值与已知为0的值之间存在很大差异。后者是utcnow()应返回的值,即IMO。根据文档,这将符合"一个知道对象用于表示不可解释的特定时刻"。