在 Python 中生成 RFC 3339 时间戳 [重复]
Posted
技术标签:
【中文标题】在 Python 中生成 RFC 3339 时间戳 [重复]【英文标题】:Generate RFC 3339 timestamp in Python [duplicate] 【发布时间】:2012-01-23 07:00:38 【问题描述】:我正在尝试在 Python 中生成 RFC 3339 UTC 时间戳。到目前为止,我已经能够做到以下几点:
>>> d = datetime.datetime.now()
>>> print d.isoformat('T')
2011-12-18T20:46:00.392227
我的问题是设置 UTC 偏移量。
根据docs,类方法datetime.now([tz])
采用可选的tz
参数,其中tz must be an instance of a class tzinfo subclass
和datetime.tzinfo
是an abstract base class for time zone information objects.
这就是我迷路的地方- tzinfo 为什么是一个抽象类,我应该如何实现它?
(注意:在php中它就像timestamp = date(DATE_RFC3339);
一样简单,这就是为什么我不明白为什么Python的方法如此复杂......)
【问题讨论】:
Further down 在您链接到的同一个文档中,它解释了如何实现它,并给出了一些示例,包括UTC
类(代表 UTC)的完整代码,FixedOffset
类(表示与 UTC 有固定偏移的时区,而不是具有 DST 和诸如此类的时区),以及其他一些。
@ruakh- 谢谢,我错过了这些例子- LocalTimezone()
类成功了。
刚发现这个类似的问题:ISO Time (ISO 8601) in Python?
【参考方案1】:
2021 年更新
在 Python 3.2 中,timezone
被添加到 datetime 模块中,让您可以轻松地将时区分配给 UTC。
>>> import datetime
>>> n = datetime.datetime.now(datetime.timezone.utc)
>>> n.isoformat()
'2021-07-13T15:28:51.818095+00:00'
上一个答案:
时区很痛苦,这可能是他们选择不将它们包含在日期时间库中的原因。
试试 pytz,它有你要找的 tzinfo: 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'
【讨论】:
@monkut-Thanks- pytz 类看起来像是另一种可行的实现,但根据 ruakh 的回答,我最终使用了文档中包含的示例。 它不会为我返回微秒:-/【参考方案2】:在 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 表示当前时间的感知日期时间对象,那么您可以 define a simple tzinfo subclass as shown in the docs to represent UTC timezone:
from datetime import datetime
utc_now = datetime.now(utc)
print(utc_now.isoformat('T'))
# -> 2015-05-19T20:32:12.610841+00:00
您还可以使用tzlocal
module 获取代表您当地时区的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。
【讨论】:
毫无疑问,Python 3.3+ 的最佳答案 @villapx: rfc 3339 是 ISO 8601 的配置文件。碰巧datetime.isoformat()
是 RFC 3339 的时区感知日期时间(这就是我使用它的原因)。
@villapx:不,这是错误的。您在误导“潜在用户”。如果 .utcoffset()
不反映 .dst()
值,那么您的 datetime
类已损坏。
@J.F.Sebastian 哦,哇,你是对的。我完全被datetime.tzinfo.dst()
documentation误导了:Note that DST offset, if applicable, has already been added to the UTC offset returned by utcoffset(), so there’s no need to consult dst() unless you’re interested in obtaining DST info separately.
我没有直接看到上面的utcoffset()
,上面写着"Note that this is intended to be the total offset from UTC."
@jrc: now() 本身可能不明确(例如,在 DST 转换期间)。【参考方案3】:
在现代 (3.x) python 上,要获取 RFC 3339 UTC 时间,您需要做的就是使用 datetime 和这一行(不需要第三方模块):
import datetime
datetime.datetime.now(datetime.timezone.utc).isoformat()
结果类似于:'2019-06-13T15:29:28.972488+00:00'
此 ISO 8601 字符串也与 RFC3339 兼容。
【讨论】:
实际上 Python 日期时间与 ISO 8601 不兼容,因为它不允许字符串以 'Z' 结尾 没错。我怎样才能得到 Z 结尾呢? @uwieuwe4 你可以在上面的结果中使用.replace('+00:00', 'Z')
。或者,只需使用 .strftime('%Y-%m-%dT%H:%M:%SZ')
而不是 .isoformat()。【参考方案4】:
我在 RFC3339 日期时间格式上苦苦挣扎,但我找到了一个合适的解决方案来双向转换 date_string datetime_object。
您需要两个不同的外部模块,因为其中一个只能在一个方向上进行转换(不幸的是):
首次安装:
sudo pip install rfc3339
sudo pip install iso8601
然后包括:
import datetime # for general datetime object handling
import rfc3339 # for date object -> date string
import iso8601 # for date string -> date object
为了不需要记住哪个模块是哪个方向,我写了两个简单的辅助函数:
def get_date_object(date_string):
return iso8601.parse_date(date_string)
def get_date_string(date_object):
return rfc3339.rfc3339(date_object)
在您的代码中,您可以像这样轻松使用:
input_string = '1989-01-01T00:18:07-05:00'
test_date = get_date_object(input_string)
# >>> datetime.datetime(1989, 1, 1, 0, 18, 7, tzinfo=<FixedOffset '-05:00' datetime.timedelta(-1, 68400)>)
test_string = get_date_string(test_date)
# >>> '1989-01-01T00:18:07-05:00'
test_string is input_string # >>> True
赫里卡!现在您可以轻松(哈哈)以可用的格式使用您的日期字符串和日期字符串。
【讨论】:
“Heureka”。丢掉“H”。【参考方案5】:我刚开始使用的另一个有用的实用程序:dateutil 库,用于时区处理和日期解析。推荐在SO附近,包括这个answer
【讨论】:
dateutil
是一个库,它提供解析日期到日期时间的功能,我认为这在生成的上下文中没有帮助具有特定格式的日期/时间字符串。【参考方案6】:
pytz 包可用于 Python 2.X 和 3.X。它实现了tzinfo
的具体子类以及其他服务,因此您不必这样做。
添加 UTC 偏移量: 导入日期时间 导入pytz
dt = datetime.datetime(2011, 12, 18, 20, 46, 00, 392227)
utc_dt = pytz.UTC.localize(dt)
现在是这样的:
print utc_dt.isoformat()
将打印:
2011-12-18T20:46:00.392227+00:00
【讨论】:
如果您只需要 UTC 时区,则不需要pytz
模块。很简单define utc tzinfo
谢谢。当我需要标准库解决方案时,我会保留您的答案。 UTC 只是最短的演示。 OP并没有特别要求它。 pytz
知道所有时区及其 DST,我觉得这很有用。
注意:get_localzone()
in my answer 返回 puts 与本地时区相对应的时区。
是的。应该是“pytz
timezone”,而不是“puts
timezone”【参考方案7】:
你确实可以使用内置的 datetime 模块。作为 @ruakh mentions,里面有例子 显示如何的页面。如果您查看有关 tzinfo你会的 看一个很长的例子,展示了许多不同的用例。这是一个的代码 您正在寻找,它是生成一个 RFC 3339 UTC 时间戳。
from datetime import tzinfo, timedelta, datetime
import time as _time
ZERO = timedelta(0)
STDOFFSET = timedelta(seconds=-_time.timezone)
if _time.daylight:
DSTOFFSET = timedelta(seconds=-_time.altzone)
else:
DSTOFFSET = STDOFFSET
DSTDIFF = DSTOFFSET - STDOFFSET
class LocalTimezone(tzinfo):
def utcoffset(self, dt):
if self._isdst(dt):
return DSTOFFSET
else:
return STDOFFSET
def dst(self, dt):
if self._isdst(dt):
return DSTDIFF
else:
return ZERO
def tzname(self, dt):
return _time.tzname[self._isdst(dt)]
def _isdst(self, dt):
tt = (dt.year, dt.month, dt.day,
dt.hour, dt.minute, dt.second,
dt.weekday(), 0, 0)
stamp = _time.mktime(tt)
tt = _time.localtime(stamp)
return tt.tm_isdst > 0
Local = LocalTimezone()
d = datetime.now(Local)
print d.isoformat('T')
# which returns
# 2014-04-28T15:44:45.758506-07:00
【讨论】:
以上是关于在 Python 中生成 RFC 3339 时间戳 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Swift 中解析/创建格式为小数秒 UTC 时区(ISO 8601、RFC 3339)的日期时间戳?
如何在 Swift 中解析/创建格式为小数秒 UTC 时区(ISO 8601、RFC 3339)的日期时间戳?