Ответ, на который ссылался Джед Смит, хорош, и я использовал его около года, но я думаю, что его можно улучшить несколькими способами:
- Приятно иметь возможность определять каждую единицу времени в терминах предыдущей единицы, вместо того, чтобы разбрасывать «волшебные» константы, такие как 3600, 86400 и т. Д., Разбросанные по всему коду.
- После долгого использования я обнаружил, что не хочу так охотно переходить к следующему устройству. Пример: и 7 дней, и 13 дней будут отображаться как «1 неделя»; Вместо этого я предпочел бы увидеть «7 дней» или «13 дней».
Вот что я придумал:
def PrettyRelativeTime(time_diff_secs):
# Each tuple in the sequence gives the name of a unit, and the number of
# previous units which go into it.
weeks_per_month = 365.242 / 12 / 7
intervals = [('minute', 60), ('hour', 60), ('day', 24), ('week', 7),
('month', weeks_per_month), ('year', 12)]
unit, number = 'second', abs(time_diff_secs)
for new_unit, ratio in intervals:
new_number = float(number) / ratio
# If the new number is too small, don't go to the next unit.
if new_number < 2:
break
unit, number = new_unit, new_number
shown_num = int(number)
return '{} {}'.format(shown_num, unit + ('' if shown_num == 1 else 's'))
Обратите внимание, что каждый кортеж в intervals
легко интерпретируется и проверяется: a 'minute'
равен 60
секундам; 'hour'
составляет 60
минут; и т. д. Единственная выдумка - установить weeks_per_month
на среднее значение; учитывая заявление, это должно быть хорошо. (И обратите внимание, что сразу видно, что последние три константы умножаются на 365,242, количество дней в году.)
Одним из недостатков моей функции является то, что она ничего не делает вне шаблона "## units": "Вчера", "только сейчас" и т. Д. Опять же, оригинальный постер не просил этих причудливых терминов, поэтому я предпочитаю свою функцию за ее краткость и удобочитаемость ее числовых констант. :)