Естественные / Относительные дни в Python
-
03-07-2019 - |
Вопрос
Мне бы нужен способ показывать естественное время для датированных элементов в Python.Аналогично тому, как Twitter будет показывать сообщение от "минуту назад", "несколько минут назад", "два часа назад", "три дня назад" и т.д.
В Django 1.0 есть метод "очеловечивания" в django.contrib.Я не использую фреймворк Django, и даже если бы использовал, он более ограничен, чем мне бы хотелось.
Пожалуйста, дайте мне (и поколениям будущих поисковиков) знать, есть ли уже хорошее рабочее решение.Поскольку это достаточно распространенная задача, я полагаю, что должно быть что-то еще.
Решение
Хотя в данный момент это и не полезно для вас, это может оказаться полезным для будущих поисковиков:Модуль babel, который имеет дело со всеми видами языковых настроек, имеет функцию для выполнения более или менее того, что вы хотите.Однако в настоящее время это только в их багажнике, а не в последней публичной версии (версия 0.9.4).Как только функциональность появится в релизе, вы могли бы сделать что-то вроде:
from datetime import timedelta
from babel.dates import format_timedelta
delta = timedelta(days=6)
format_timedelta(delta, locale='en_US')
u'1 week'
Это взято прямо из документация babel по форматированию временной дельты.Это, по крайней мере, поможет вам пройти часть пути.Это не будет делать размытости до уровня "несколько минут назад" и тому подобного, но это будет делать "n минут" и т.д.правильно составлено во множественном числе.
Как бы то ни было, модуль babel также содержит функции для форматирования дат и времени в соответствии с языковым стандартом, что может быть полезно, когда разница во времени велика.
Другие советы
Конкретные даты в Twitter интересны тем, что они относительны только для первого дня.Через 24 часа они просто показывают месяц и число.Через год они начинают показывать последние две цифры года.Вот пример функции, которая делает что-то более похожее на относительные даты Twitter, хотя она также всегда показывает год через 24 часа.Это только язык США, но вы всегда можете изменить его по мере необходимости.
# tested in Python 2.7
import datetime
def prettydate(d):
diff = datetime.datetime.utcnow() - d
s = diff.seconds
if diff.days > 7 or diff.days < 0:
return d.strftime('%d %b %y')
elif diff.days == 1:
return '1 day ago'
elif diff.days > 1:
return '{} days ago'.format(diff.days)
elif s <= 1:
return 'just now'
elif s < 60:
return '{} seconds ago'.format(s)
elif s < 120:
return '1 minute ago'
elif s < 3600:
return '{} minutes ago'.format(s/60)
elif s < 7200:
return '1 hour ago'
else:
return '{} hours ago'.format(s/3600)
Есть гуманизированная упаковка:
>>> import humanize
>>> import datetime
>>> humanize.naturalday(datetime.datetime.now())
'today'
>>> humanize.naturalday(datetime.datetime.now() - datetime.timedelta(days=1))
'yesterday'
>>> humanize.naturalday(datetime.date(2007, 6, 5))
'Jun 05'
>>> humanize.naturaldate(datetime.date(2007, 6, 5))
'Jun 05 2007'
>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=1))
'a second ago'
>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=3600))
'an hour ago'
Примеры для вашего варианта использования:
>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=36000))
'10 hours ago'
>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=360000))
'4 days ago'
>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=3600000))
'a month ago'
Кроме того (см. ссылку выше), он также поддерживает гуманизацию:
- целые числа
- размеры файлов
- плавающие значения (для дробных чисел)
Или вы могли бы легко адаптироваться timesince.py из Django, который имеет только 2 другие зависимости от самого себя:один для перевода (который вам, возможно, не понадобится) и один для часовых поясов (который можно легко адаптировать).
Кстати, У Django есть лицензия BSD который является довольно гибким, вы сможете использовать его в любом проекте, который вы используете в данный момент.
Вы ищете что-нибудь что - то вроде этого (Печать относительных дат на Python)?