简体   繁体   English

将 RFC 3339 时间转换为标准 Python 时间戳

[英]Convert an RFC 3339 time to a standard Python timestamp

Is there an easy way to convert an RFC 3339 time into a regular Python timestamp?有没有一种简单的方法可以将RFC 3339时间转换为常规的 Python 时间戳?

I've got a script which is reading an ATOM feed and I'd like to be able to compare the timestamp of an item in the ATOM feed to the modification time of a file.我有一个脚本正在读取 ATOM 提要,我希望能够将 ATOM 提要中项目的时间戳与文件的修改时间进行比较。

I notice from the ATOM spec , that ATOM dates include a time zone offset ( Z<a number> ) but, in my case, there's nothing after the Z so I guess we can assume GMT.我从ATOM 规范中注意到,ATOM 日期包括时区偏移量( Z<a number> ),但就我而言, Z之后没有任何内容,所以我想我们可以假设 GMT。

I suppose I could parse the time with a regex of some sort but I was hoping Python had a built-in way of doing it that I just haven't been able to find.我想我可以用某种正则表达式来解析时间,但我希望 Python 有一种内置的方式来做它,我只是无法找到。

You don't include an example, but if you don't have a Z-offset or timezone, and assuming you don't want durations but just the basic time, then maybe this will suit you:您没有包含示例,但是如果您没有 Z 偏移量或时区,并且假设您不需要持续时间而只需要基本时间,那么这可能适合您:

import datetime as dt
>>> dt.datetime.strptime('1985-04-12T23:20:50.52', '%Y-%m-%dT%H:%M:%S.%f')
datetime.datetime(1985, 4, 12, 23, 20, 50, 520000)

The strptime() function was added to the datetime module in Python 2.5 so some people don't yet know it's there. strptime() 函数被添加到 Python 2.5 的 datetime 模块中,所以有些人还不知道它在那里。

Edit : The time.strptime() function has existed for a while though, and works about the same to give you a struct_time value:编辑: time.strptime() 函数已经存在一段时间了,它的工作原理大致相同,可以为您提供 struct_time 值:

>>> ts = time.strptime('1985-04-12T23:20:50.52', '%Y-%m-%dT%H:%M:%S.%f')
>>> ts
time.struct_time(tm_year=1985, tm_mon=4, tm_mday=12, tm_hour=23, tm_min=20, tm_sec=50, tm_wday=4, tm_yday=102, tm_isdst=-1)
>>> time.mktime(ts)
482210450.0

I struggled with RFC3339 datetime format a lot, but I found a suitable solution to convert date_string <=> datetime_object in both directions.我在 RFC3339 日期时间格式上苦苦挣扎,但我找到了一个合适的解决方案来在两个方向转换 date_string <=> datetime_object。

You need two different external modules, because one of them is is only able to do the conversion in one direction (unfortunately):您需要两个不同的外部模块,因为其中之一只能在一个方向上进行转换(不幸的是):

first install:首先安装:

sudo pip install rfc3339
sudo pip install iso8601

then include:然后包括:

import datetime     # for general datetime object handling
import rfc3339      # for date object -> date string
import iso8601      # for date string -> date object

For not needing to remember which module is for which direction, I wrote two simple helper functions:为了不需要记住哪个模块是哪个方向,我写了两个简单的辅助函数:

def get_date_object(date_string):
  return iso8601.parse_date(date_string)

def get_date_string(date_object):
  return rfc3339.rfc3339(date_object)

which inside your code you can easily use like this:在您的代码中,您可以像这样轻松使用:

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!赫里卡! Now you can easily ( haha ) use your date strings and date strings in a useable format.现在您可以轻松(哈哈)以可用格式使用您的日期字符串和日期字符串。

No builtin, afaik.没有内置,afaik。

feed.date.rfc3339 This is a Python library module with functions for converting timestamp strings in RFC 3339 format to Python time float values, and vice versa. feed.date.rfc3339这是一个 Python 库模块,具有将 RFC 3339 格式的时间戳字符串转换为 Python 时间浮点值的函数,反之亦然。 RFC 3339 is the timestamp format used by the Atom feed syndication format. RFC 3339 是 Atom 提要联合格式使用的时间戳格式。

It is BSD-licensed.它是 BSD 许可的。

http://home.blarg.net/~steveha/pyfeed.html http://home.blarg.net/~steveha/pyfeed.html

(Edited so it's clear I didn't write it. :-) (编辑所以很明显我没有写它。:-)

http://pypi.python.org/pypi/iso8601/似乎能够解析 iso 8601,它是 RFC 3339 的一个子集,也许这可能有用,但同样,不是内置的。

If you're using Django, you could use Django's function parse_datetime :如果您使用的是 Django,则可以使用 Django 的函数parse_datetime

>>> from django.utils.dateparse import parse_datetime
>>> parse_datetime("2016-07-19T07:30:36+05:00")
datetime.datetime(2016, 7, 19, 7, 30, 36, tzinfo=<django.utils.timezone.FixedOffset object at 0x101c0c1d0>)

http://bugs.python.org/issue15873 (duplicate of http://bugs.python.org/issue5207 ) http://bugs.python.org/issue15873 (重复http://bugs.python.org/issue5207

Looks like there isn't a built-in as of yet.看起来目前还没有内置的。

feedparser.py provides robust/extensible way to parse various date formats that may be encountered in real-world atom/rss feeds: feedparser.py提供了强大/可扩展的方式来解析在现实世界中的 atom/rss 提要中可能遇到的各种日期格式:

>>> from feedparser import _parse_date as parse_date
>>> parse_date('1985-04-12T23:20:50.52Z')
time.struct_time(tm_year=1985, tm_mon=4, tm_mday=12, tm_hour=23, tm_min=20,
                 tm_sec=50, tm_wday=4, tm_yday=102, tm_isdst=1)

The new datetime.fromisoformat(date_string) method which was added in Python 3.7 will parse most RFC 3339 timestamps, including those with time zone offsets. Python 3.7添加的新datetime.fromisoformat(date_string)方法将解析大多数 RFC 3339 时间戳,包括具有时区偏移的时间戳。 It's not a full implementation, so be sure to test your use case.这不是一个完整的实现,所以一定要测试你的用例。

>>> from datetime import datetime
>>> datetime.fromisoformat('2011-11-04')
datetime.datetime(2011, 11, 4, 0, 0)
>>> datetime.fromisoformat('2011-11-04T00:05:23')
datetime.datetime(2011, 11, 4, 0, 5, 23)
>>> datetime.fromisoformat('2011-11-04 00:05:23.283')
datetime.datetime(2011, 11, 4, 0, 5, 23, 283000)
>>> datetime.fromisoformat('2011-11-04 00:05:23.283+00:00')
datetime.datetime(2011, 11, 4, 0, 5, 23, 283000, tzinfo=datetime.timezone.utc)
>>> datetime.fromisoformat('2011-11-04T00:05:23+04:00')   
datetime.datetime(2011, 11, 4, 0, 5, 23,
    tzinfo=datetime.timezone(datetime.timedelta(seconds=14400)))

try this, it works fine for me试试这个,它对我来说很好用

datetime_obj =  datetime.strptime("2014-01-01T00:00:00Z", '%Y-%m-%dT%H:%M:%SZ')

or

datetime_obj = datetime.strptime("Mon, 01 Jun 2015 16:41:40 GMT", '%a, %d %b %Y %H:%M:%S GMT')

在另一个问题中遇到了很棒的dateutil.parser模块,并在我的 RFC3339 问题上尝试了它,它似乎比这个问题中的任何其他回答都更理智地处理了我抛出的所有问题。

Using Python 3, you can use RegEx to break the RFC 3339 timestamp into its components.使用 Python 3,您可以使用 RegEx 将 RFC 3339 时间戳分解为其组件。 Then, directly create the datetime object, no additional modules needed:然后,直接创建 datetime 对象,不需要额外的模块:

import re
import datetime

def parse_rfc3339(dt):
    broken = re.search(r'([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(\.([0-9]+))?(Z|([+-][0-9]{2}):([0-9]{2}))', dt)
    return(datetime.datetime(
        year = int(broken.group(1)),
        month = int(broken.group(2)),
        day = int(broken.group(3)),
        hour = int(broken.group(4)),
        minute = int(broken.group(5)),
        second = int(broken.group(6)),
        microsecond = int(broken.group(8) or "0"),
        tzinfo = datetime.timezone(datetime.timedelta(
            hours = int(broken.group(10) or "0"),
            minutes = int(broken.group(11) or "0")))))

This example theads missing timezones or microseconds as "0" but might need additional error checking.此示例将缺少时区或微秒的广告设为“0”,但可能需要额外的错误检查。 Cheers, Alex干杯,亚历克斯

The simplest solution for me has been dateutil python standart library.对我来说最简单的解决方案是dateutil python 标准库。

from dateutil.parser import parse

dt = "2020-11-23T11:08:23.022277705Z"
print(parse(dt))

Output:输出:

2020-11-23 11:08:23.022277+00:00

If you don't need the timezone element, just simply set timezone info to None如果您不需要时区元素,只需将时区信息设置为

print(parse(t).replace(tzinfo=None))

The output is a nice and clean datetime object:输出是一个漂亮而干净的日期时间对象:

2020-11-23 11:08:23.022277

You could use a Google API Core package.您可以使用 Google API 核心包。 They have a really straightforward Datetime to RFC 3339 conversion function.他们有一个非常简单的日期时间到 RFC 3339 转换功能。 You can find more info in their docs .您可以在他们的文档中找到更多信息。

Its usage is as simple as:它的用法很简单:

from google.api_core.datetime_helpers import to_rfc3339

rfc3339_str = to_rfc3339(datetime.now())

They even have a function that works the other way around from_rfc3339 and from_rfc3339_nanos .他们甚至有一个功能可以from_rfc3339from_rfc3339_nanos

I have been doing a deep dive in dateimes and RFC3339 and recently come across the arrow library and have just used and solved my problem:我一直在深入研究日期时间和 RFC3339,最近遇到了箭头库,刚刚使用并解决了我的问题:

import arrow

date_string = "2015-11-24 00:00:00+00:00"
my_datetime = arrow.get(date_string).datetime

rfc3339 库: http ://henry.precheur.org/python/rfc3339

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM