Естественные/относительные дни в Python
Мне бы хотелось показать естественные времена для датированных элементов в Python. Подобно тому, как Twitter будет показывать сообщение с "момента назад", "несколько минут назад", "два часа назад", "три дня назад" и т.д.
Django 1.0 имеет метод "humanize" в django.contrib. Я не использую фреймворк Django, и даже если бы я был, он был бы более ограниченным, чем хотелось бы.
Пожалуйста, позвольте мне (и поколениям будущих искателей) знать, есть ли уже хорошее рабочее решение. Поскольку это достаточно распространенная задача, я полагаю, что должно быть что-то.
Ответы
Ответ 1
В то время, когда вам это не полезно, это может быть так для будущих искателей:
Модуль 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'
Это взято прямо из документация по барабанам по форматированию дельта-времени. Это, по крайней мере, даст вам часть пути. Это не приведет к размытию до уровня "моментов назад" и тому подобное, но оно будет делать "n минут" и т.д. Правильно плюрализовано.
Для того, что стоит, модуль babel также содержит функции для форматирования дат и времени в соответствии с локалью, что может быть полезно, когда дельта времени велика.
Ответ 2
Даты 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)
Ответ 3
Или вы можете легко адаптировать timesince.py из Django, у которого есть только две другие зависимости: одна для перевода (что вам может и не понадобиться ) и один для часовых поясов (которые можно легко адаптировать).
Кстати, Django имеет лицензию BSD, которая довольно гибкая, вы сможете использовать ее в любом проекте, который вы сейчас используете используя.
Ответ 4
Существует пакет гуманизации:
>>> 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'
Далее (см. ссылку выше) он также поддерживает гуманизацию:
- целые числа
- размер файла
- плавает (до дробных чисел)
Ответ 5
Вы ищете что-то вроде этого (Печать относительных дат в Python)?