如何在Python中获取UTC时间?

247

我如何获取UTC时间,即自1970年1月1日Unix纪元以来的毫秒数?


3
如何获取一个“带有时区信息”的datetime.today()值? - jfs
9个回答

324

对于Python 2代码,请使用datetime.utcnow()

from datetime import datetime
datetime.utcnow()

对于Python 3,请使用datetime.now(timezone.utc)(2.x解决方案在3.x文档中有一个巨大的警告,虽然技术上可行):

from datetime import datetime, timezone
datetime.now(timezone.utc)

当您需要计算两个日期之间所花费的时间时,您只需要减去结束日期和起始日期即可。这种减法的结果是一个timedelta对象。

来自Python文档:

class datetime.timedelta([days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]])

这意味着默认情况下,您可以获取其定义中提到的任何字段 - 天数,秒数,微秒数,毫秒数,分钟数,小时数,周数。此外,timedelta实例具有total_seconds()方法,该方法:

返回持续时间包含的总秒数。 等价于 (td.microseconds + (td.seconds + td.days * 24 * 3600) * 106) / 106使用真除法计算。


32
datetime.utcnow() 可能会给你带来一个不太好的惊喜,尽管名称中含有 "utc",但它并没有返回一个带时区信息的对象。我认为这是一个很大的问题,因此我更喜欢下面提供的解决方案。 参见链接:"datetime对象没有时区信息应被视为应用程序中的“错误”。" https://julien.danjou.info/python-and-timezones/ - Tim Richardson
4
所谓"naive datetime object"(即没有设置时区信息的日期时间对象)的概念确实有其作用: 我希望我的闹钟在每天的06:00:00响起,无论我身处世界的哪个地方。此外,在计算机游戏中,它还允许存在"虚拟时钟": 在我的幻想世界中,现在是下午5点。如果强制给日期时间对象设置时区,将会很麻烦,特别是在使用时间差运算时。 - DustByte

201

时区感知datetime 对象, datetime.utcnow() 不同:

from datetime import datetime,timezone
now_utc = datetime.now(timezone.utc)

自 Unix 纪元以来的毫秒时间戳:

datetime.now(timezone.utc).timestamp() * 1000

37
根据 Python 3 的文档,这是推荐的方法。 - roskakori
4
清洁简单!应该是首选方式。 - Marry35
5
是的,现在这应该是首选的方法。当最初提出问题时,timezone.utc不存在。 - Mark Ransom
4
如果您希望使用本地时间(例如,为了更方便地向用户显示),但仍保持时区安全性,您可以使用datetime.now().astimezone() - Martin Cejp

47

以最接近您原始表单的形式:

import datetime

def UtcNow():
    now = datetime.datetime.utcnow()
    return now

如果你需要知道从1970-01-01开始的秒数,而不是使用Python的原生datetime,请使用以下方法代替:
return (now - datetime.datetime(1970, 1, 1)).total_seconds()

Python具有与JavaScript中您可能习惯的命名约定不一致的特点,请参阅PEP 8。此外,一个仅返回另一个函数结果的函数相当愚蠢;如果只是为了使其更易访问,您可以通过简单地赋值来为函数创建另一个名称。上面的第一个示例可以替换为:

utc_now = datetime.datetime.utcnow

现在以上所有的内容都被认为是过时的了。Python 3.2 引入了 datetime.timezone,这样一个适用于 UTC 的合适的 tzinfo 就可以供所有人使用了。所以现代版本变成了:
def utc_now():
   return datetime.datetime.now(tz=datetime.timezone.utc)

1
@J.F.Sebastian 是的,但请看我之前发表的评论——这是最接近问题代码形式的表达方式。除非相关,否则没有必要通过引入离题内容来让人们感到困惑。 - Mark Ransom
2
(now - datetime.datetime(1970, 1, 1)).total_seconds() ... 那么 time.time() 呢? - Chris
要获取时间戳,您可以使用以下方法:
  • time.time() - 转换为整数以去除毫秒。
  • int(datetime.datetime.nowutc("%s")) - 返回一个字符串,因此我将其转换为整数。
- hectorcanto
1
datetime.datetime.utcnow() 不返回带时区信息的日期时间,这真的不是一个好主意,迟早会有人发现这是多么可怕的事情。 - Tim Richardson
1
@TimRichardson 我不反对,但在回答这个问题的时候,没有其他选择 - 即使是对于UTC,Python也没有包括任何tzinfo对象。 - Mark Ransom
显示剩余2条评论

22
import datetime
import pytz

# datetime object with timezone awareness:
datetime.datetime.now(tz=pytz.utc)

# seconds from epoch:
datetime.datetime.now(tz=pytz.utc).timestamp() 

# ms from epoch:
int(datetime.datetime.now(tz=pytz.utc).timestamp() * 1000) 

由于时区数据库/包已移入Std Lib,因此pytz现已被弃用。 - Marc
@Marc pytz没有被弃用。 - wim

16

具备时区意识,无需外部依赖:

from datetime import datetime, timezone

def utc_now():
    return datetime.utcnow().replace(tzinfo=timezone.utc)

1
为了以祖鲁格式打印它,这是正确的方法:datetime.utcnow().replace(tzinfo=timezone.utc).strftime('%Y-%m-%dT%H:%M:%SZ') - Imtiaz Shakil Siddique
1
它与datetime.now(timezone.utc)有什么不同吗?只是好奇,因为我相信结果完全相同。 - Gagan Deep Singh
1
@GaganDeepSingh 两者都提供了完全相同的 datetime 对象。(有时候到达同一目的地可能有多条路径。).replace(tzinfo=timezone.utc) 只是设置了 .tzinfo 成员,而默认情况下该成员不幸地为 None - Mateen Ulhaq

10

从datetime.datetime中,您已经可以使用strftime方法导出时间戳。以下是您的函数示例:

import datetime
def UtcNow():
    now = datetime.datetime.utcnow()
    return int(now.strftime("%s"))
如果您想要微秒级别的精度,您需要更改导出字符串并进行浮点数转换,例如:return float(now.strftime("%s.%f"))

1
当你可以直接得到数字时,将其转换为字符串然后再转回数字有什么意义呢? - Mark Ransom
重点是您可能想要更改函数中的某些内容,因此最好坚持使用datetime对象,而不是使用time.time(), 您还可以使用time.mktime(now.timetuple())直接转换为int。 无论如何,对于这种简单情况,time.time()也是一个有效的选择。 我觉得奇怪的是通过timedelta查找秒数。 - hectorcanto
请注意,strftime(“%s”)是依赖于平台的,在Windows上无法工作。(至少在我的Windows 10上不行)。 - Julian Kirsch

7

你可以使用 datetime 库来获取世界标准时间或本地时间。

import datetime

utc_time = datetime.datetime.utcnow() 
print(utc_time.strftime('%Y%m%d %H%M%S'))

这个2021年的答案对谈话有什么补充?它与近10年前被接受的答案中展示的方法相同。 - wim

5
为什么所有的回复都基于日期时间而不是时间?我认为这是最简单的方式!
import time
nowgmt = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())
print(nowgmt)

nowgmt将是一个字符串,这比拥有一个日期时间对象更不灵活。 - sezanzeb

-2

准确来说,UTC格式至少需要T字母:

>>> a=(datetime.datetime.now(timezone.utc))
>>> a.strftime("%Y-%m-%dT%H:%M:%SZ")
'2022-11-28T16:42:17Z'

UTC与您选择表示时间的格式无关。 - Pranav Hosangadi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接