Подтвердить что ты не робот

Естественные/относительные дни в Python

Мне бы хотелось показать естественные времена для датированных элементов в Python. Подобно тому, как Twitter будет показывать сообщение с "момента назад", "несколько минут назад", "два часа назад", "три дня назад" и т.д.

Django 1.0 имеет метод "humanize" в django.contrib. Я не использую фреймворк Django, и даже если бы я был, он был бы более ограниченным, чем хотелось бы.

Пожалуйста, позвольте мне (и поколениям будущих искателей) знать, есть ли уже хорошее рабочее решение. Поскольку это достаточно распространенная задача, я полагаю, что должно быть что-то.

4b9b3361

Ответ 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'

Далее (см. ссылку выше) он также поддерживает гуманизацию:

  • целые числа
  • размер файла
  • плавает (до дробных чисел)