Преобразование времени RFC 3339 в стандартную метку времени Python
Есть ли простой способ конвертировать RFC 3339 в обычную временную метку Python?
У меня есть script, который читает фид ATOM, и мне бы хотелось сравнить временную метку элемента в фиде ATOM с временем изменения файла.
Я заметил из спецификацию ATOM, что даты ATOM включают смещение часового пояса (Z<a number>
), но в моем случае ничего нет после Z
, поэтому я предполагаю, что мы можем предположить GMT.
Я предполагаю, что могу разобрать время с некоторым регулярным выражением, но я надеялся, что у Python есть встроенный способ сделать это, что я просто не смог найти.
Ответы
Ответ 1
Нет встроенного, afaik.
feed.date.rfc3339
Это библиотечный модуль Python с функциями преобразования строк timestamp в формате RFC 3339 в значения времени плавания времени Python и наоборот. RFC 3339 - это формат временной метки, используемый в формате синдикации Atom.
Лицензия BSD.
http://home.blarg.net/~steveha/pyfeed.html
(Отредактировано так, что я понял, что не написал его.: -)
Ответ 2
Вы не включаете пример, но если у вас нет 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)
Функция strptime() была добавлена в модуль datetime в Python 2.5, поэтому некоторые люди пока этого не знают.
Изменить: функция 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
Ответ 3
http://pypi.python.org/pypi/iso8601/, похоже, способен анализировать iso 8601, который RFC 3339 является подмножеством, возможно, это может быть полезно, но снова, не встроенный.
Ответ 4
http://bugs.python.org/issue15873 (дубликат http://bugs.python.org/issue5207)
Похоже, пока нет встроенного модуля.
Ответ 5
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)
Ответ 6
Я долго боролся с форматом даты и времени 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
Эврика! Теперь вы можете легко (ха-ха) использовать строки даты и строки даты в удобном для использования формате.
Ответ 7
Если вы используете 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>)
Ответ 8
попробуйте это, он отлично работает для меня
datetime_obj = datetime.strptime("2014-01-01T00:00:00Z", '%Y-%m-%dT%H:%M:%SZ')
или
datetime_obj = datetime.strptime("Mon, 01 Jun 2015 16:41:40 GMT", '%a, %d %b %Y %H:%M:%S GMT')
Ответ 9
Используя Python 3, вы можете использовать RegEx, чтобы разбить временную метку RFC 3339 на ее компоненты.
Затем непосредственно создайте объект 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")))))
В этом примере theads отсутствуют временные интервалы или микросекунды как "0", но может потребоваться дополнительная проверка ошибок.
Привет, Алекс
Ответ 10
Библиотека rfc3339: http://henry.precheur.org/python/rfc3339
Ответ 11
Прошел через awesome dateutil.parser модуль в другом вопросе и попробовал его по моей проблеме RFC3339, и он, похоже, обрабатывает все, что я бросаю на него с большим здравым смыслом что любой из других ответов в этом вопросе.