如何以 UTC 获取当前时间(现在)?

Posted

技术标签:

【中文标题】如何以 UTC 获取当前时间(现在)?【英文标题】:How can I get the current time (now) in UTC? 【发布时间】:2011-03-20 16:02:12 【问题描述】:

我有一个 python 日期时间对象(表示从现在开始的五分钟),我想将其转换为 UTC。我打算以 RFC 2822 格式输出它以放入 HTTP 标头,但我不确定这对这个问题是否重要。我在这个网站上找到了一些关于转换时间对象的信息,这样看起来更简单,但是这次我真的想使用 datetime 对象,因为我正在使用 timedeltas 来调整它们:

我尝试过这样的事情:

from datetime import datetime, timedelta

now = datetime.now()
fiveMinutesLater = datetime.now() + timedelta(minutes=5)
fiveMinutesLaterUtc = ???

时间或日期时间模块中的任何内容看起来都不会对我有所帮助。似乎我可以通过将 datetime 对象传递给 3 或 4 个函数来做到这一点,但我想知道是否有更简单的方法。

我不希望使用第三方模块,但如果这是唯一合理的选择,我可能会。

【问题讨论】:

相关标题:How do I convert local time to UTC in Python? 字符串:***.com/questions/79797/… 相关***.com/a/8778548/431528 【参考方案1】:

您可以在 email.Utils 模块中使用 formatdate 方法,如下所示

>>> from email.Utils import formatdate
>>> print formatdate()
Sun, 25 Jul 2010 04:02:52 -0000

以上是 RFC 2822 格式的日期时间。默认情况下它返回 UTC 时间,但如果您需要本地时间,您可以调用 formatdate(localtime=True)。

更多信息请查看http://docs.python.org/library/email.mime.html#module-email.util

【讨论】:

它在 Python 3 中不起作用;你可以use email.utils (lowecase) instead【参考方案2】:

首先,您需要通过设置其tzinfo 成员来确保日期时间是可识别时区的对象:

http://docs.python.org/library/datetime.html#datetime.tzinfo

然后您可以使用.astimezone() 函数对其进行转换:

http://docs.python.org/library/datetime.html#datetime.datetime.astimezone

【讨论】:

根据文档,我需要提出一个 tzinfo 类的子类来提出一个对象,我可以将它传递给“now”函数以使其了解我的服务器的时区.这似乎有点复杂。有谁知道更简单的方法?如果我找到更简单的方法,我会在这里发布。 @mikez302 - 查看 pytz 模块。它实际上是一个包含所有常见时区的 datetime.tzinfo 时区定义的数据库。 @EliasZamaria:要将本地时区作为pytz tzinfo 对象,您可以use tzlocal.get_localzone() 这在 Python 3.3 中得到了简化(支持 .astimezone() 将天真的日期时间对象的时区设置为本地(系统)时区,并在 Python 3.6 中进一步简化,允许您简单地使用 @ 987654330@ -- 详见Carlos A. Ibarra's answer。【参考方案3】:

我找到了一种获取当前时间的方法,向其中添加一个 timedelta 对象,将结果转换为 UTC,并在 RFC 2822 中输出:

time.strftime("%a, %d-%b-%Y %H:%M:%S GMT",
    time.gmtime(time.time() + datetime.timedelta(minutes=5).seconds))

这并没有完全回答我的问题,但我把它放在这里是因为它可能会帮助我遇到的其他人。

编辑:我想补充一点,这个技巧只有在 timedelta 小于 1 天时才有效。如果您想要使用任何类型的 timedelta 值的东西,您可以使用timedelta.total_seconds()(适用于 Python 2.7 及更高版本)或86400*timedelta.days + timedelta.seconds。我实际上还没有尝试过,所以我不能 100% 确定它是否会起作用。

【讨论】:

注意:%b 可能取决于区域设置。 Use email.utils.formatdate instead。无关:86400*timedelta.days + timedelta.seconds 如果您需要支持 Python 2.6+ 并且不关心微秒,则始终可以使用。【参考方案4】:

对于那些最终在这里寻找将日期时间对象转换为自 UNIX 纪元以来的 UTC 秒数的方法的人:

import time
import datetime

t = datetime.datetime.now()
utc_seconds = time.mktime(t.timetuple())

【讨论】:

这不准确,来自 mktime doc: Convert a time tuple in local time to seconds since the Epoch。 这不是 OP 提出的问题的答案。 :( 注意:本地时间可能不明确(例如,在“回退”DST 转换期间),mktime() 可能返回错误值的概率为 50%。如果本地时区在过去/将来有/将有不同的 utc 偏移量(许多时区都有)并且 C mktime() 不使用 tz 数据库(例如,在 Windows 上),它也会失败。将表示本地时间的天真日期时间对象转换为 UTC 的可移植解决方案是 use tzlocal.get_localzone() to get the local timezone as pytz tzinfo object【参考方案5】:

从日期字符串转换为 UTC:

from time import mktime
from datetime import datetime

mktime(datetime.utctimetuple(datetime.strptime("20110830_1117","%Y%m%d_%H%M")))

【讨论】:

这不起作用 --- mktime 使用本地时区。见***.com/questions/2956886/…【参考方案6】:

运行此程序以获取 UTC 的原始日期时间(并添加五分钟):

>>> from datetime import datetime, timedelta
>>> datetime.utcnow()
datetime.datetime(2021, 1, 26, 15, 41, 52, 441598)
>>> datetime.utcnow() + timedelta(minutes=5)
datetime.datetime(2021, 1, 26, 15, 46, 52, 441598)

如果您希望使用可识别时区的日期时间对象,请在 Python 3.2 或更高版本中运行:

>>> from datetime import datetime, timezone
>>> datetime.now(timezone.utc)
datetime.datetime(2021, 1, 26, 15, 43, 54, 379421, tzinfo=datetime.timezone.utc)

【讨论】:

奇怪的是,没有人提到 utcnow() returns 和 "naive" datetime object -- with no timezone info,——所以这很可能不是你想要的。文档甚至对此有警告。 我已经编辑了答案,提供了一个简单的日期时间和一个有意识的日期时间的选项。【参考方案7】:

解决方案 很棒 Delorean lib:

>>> import datetime
>>> import delorean
>>> dt = datetime.datetime.now()
>>> dl = delorean.Delorean(dt, timezone='US/Pacific')
>>> dl.shift('UTC')
Delorean(datetime=2015-03-27 03:12:42.674591+00:00, timezone=UTC)

>>> dl.shift('UTC').datetime
datetime.datetime(2015, 3, 27, 3, 12, 42, 674591, tzinfo=<UTC>)

>>> dl.shift('EST').datetime
datetime.datetime(2015, 3, 26, 22, 12, 42, 674591, tzinfo=<StaticTzInfo 'EST'>)

它允许在不同时区之间轻松转换日期时间

【讨论】:

鉴于delorean's author does not understand the difference between .now() and .now(tz),我不会太相信它。【参考方案8】:

这是一个适用于 Python 2 和 3 的 stdlib 解决方案(没有第 3 方模块)。

以 RFC 2822 格式获取当前 UTC 时间:

>>> from email.utils import formatdate
>>> formatdate(usegmt=True)
'Fri, 27 Mar 2015 08:29:20 GMT'

获取未来 5 分钟后的 UTC 时间:

#!/usr/bin/env python
import time
from email.utils import formatdate

print(formatdate(time.time() + 300, usegmt=True)) # 5 minutes into the future
# -> Fri, 27 Mar 2015 08:34:20 GMT

【讨论】:

【参考方案9】:

使用以下内容:

from datetime import timezone
utc_datetime = local_datetime.astimezone().astimezone(timezone.utc).replace(tzinfo=None)

假设一个简单的日期时间对象具有本地日期时间,您可以使用以下方法调用序列将其转换为表示相同 UTC 时间的简单 UTC 日期时间(使用 Python 3.6.3 测试)。

    astimezone() 添加本地时区,使其不再幼稚。 astimezone(timezone.utc) 将其从本地转换为 UTC。 replace(tzinfo=None) 删除时区,所以它再次幼稚,但现在是 UTC

例子:

>>> local_datetime = datetime.now()
>>> local_datetime
datetime.datetime(2019, 12, 14, 10, 30, 37, 91818)
>>> local_datetime.astimezone()
datetime.datetime(2019, 12, 14, 10, 30, 37, 91818, tzinfo=datetime.timezone(datetime.timedelta(-1, 68400), 'Eastern Standard Time'))
>>> local_datetime.astimezone().astimezone(timezone.utc)
datetime.datetime(2019, 12, 14, 15, 30, 37, 91818, tzinfo=datetime.timezone.utc)
>>> local_datetime.astimezone().astimezone(timezone.utc).replace(tzinfo=None)
datetime.datetime(2019, 12, 14, 15, 30, 37, 91818)

注意:第一个 astimezone() 并不是真正需要的,因为 Python 文档中有这个注释:

3.6 版更改:现在可以调用 astimezone() 方法 假定代表系统本地时间的幼稚实例。

【讨论】:

谢谢!因此,只需 local_datetime.astimezone(timezone.utc) 如果您对拥有一个 timezone-aware datetime 对象感到满意并且在 Python 3.6 或更高版本上运行。此答案不适用于 Python

以上是关于如何以 UTC 获取当前时间(现在)?的主要内容,如果未能解决你的问题,请参考以下文章

如何在内核中获取当前时间(UTC

如何以日期时间格式 PHP 获取当前时间? [复制]

如何像 Java 一样获取自 1970 年以来的当前时间戳(以毫秒为单位)

如何将当前 UTC 时间转换为 Linux 时间戳 [重复]

Android获取当前UTC时间[重复]

导入 pytz 失败时如何获取太平洋时区的当前时间?