在Python中生成RFC 3339时间戳

93 投票
7 回答
122797 浏览
提问于 2025-04-17 08:37

我想在Python中生成一个RFC 3339格式的UTC时间戳。到目前为止,我已经做到了一些事情:

>>> d = datetime.datetime.now()
>>> print d.isoformat('T')
2011-12-18T20:46:00.392227

我遇到的问题是设置UTC时区偏移。

根据文档,类方法datetime.now([tz])可以接受一个可选的tz参数,而这个tz必须是一个tzinfo类的实例,并且datetime.tzinfo时间区信息对象的抽象基类。

这让我感到困惑——为什么tzinfo是一个抽象类,我应该怎么去实现它呢?


(注意:在PHP中,这个过程简单得多,只需要timestamp = date(DATE_RFC3339);,所以我不明白为什么Python的方法这么复杂……)

7 个回答

15

在现代的 Python(3.x 版本)中,要获取符合 RFC 3339 标准的 UTC 时间,你只需要使用 datetime 这个模块,并写一行简单的代码(不需要任何第三方模块):

import datetime
datetime.datetime.now(datetime.timezone.utc).isoformat()

得到的结果类似于:'2019-06-13T15:29:28.972488+00:00'

这个 ISO 8601 格式的字符串也是符合 RFC 3339 标准的。

45

在Python 3.3及以上版本中:

>>> from datetime import datetime, timezone                                
>>> local_time = datetime.now(timezone.utc).astimezone()
>>> local_time.isoformat()
'2015-01-16T16:52:58.547366+01:00'

如果你使用的是较旧的Python版本,而你只需要一个表示当前UTC时间的“有时区”的日期时间对象,那么你可以按照文档中的示例定义一个简单的tzinfo子类来表示UTC时区

from datetime import datetime

utc_now = datetime.now(utc)
print(utc_now.isoformat('T'))
# -> 2015-05-19T20:32:12.610841+00:00

你也可以使用tzlocal模块来获取表示你本地时区的pytz时区:

#!/usr/bin/env python
from datetime import datetime
from tzlocal import get_localzone # $ pip install tzlocal

now = datetime.now(get_localzone())
print(now.isoformat('T'))

这个方法在Python 2和3中都能使用。

98

更新于2021年

在Python 3.2版本中,新增了timezone功能到日期时间模块,这样你就可以轻松地给UTC时间设置时区了。

import datetime

n = datetime.datetime.now(datetime.timezone.utc)
n.isoformat() # '2021-07-13T15:28:51.818095+00:00'

之前的回答:

时区问题很麻烦,这可能就是他们在日期时间库中没有包含它们的原因。

可以试试pytz,它有你需要的时区信息: http://pytz.sourceforge.net/

你需要先创建一个datetime对象,然后像下面这样应用时区,这样你的.isoformat()输出就会包含你想要的UTC偏移量:

d = datetime.datetime.utcnow()
d_with_timezone = d.replace(tzinfo=pytz.UTC)
d_with_timezone.isoformat()

'2017-04-13T14:34:23.111142+00:00'

或者,直接使用UTC时间,在最后加一个"Z"(代表Zulu时区)来标记这个时间是UTC。

d = datetime.datetime.utcnow() # <-- get time in UTC
print d.isoformat("T") + "Z"

'2017-04-13T14:34:23.111142Z'

撰写回答