/usr/lib/python3/dist-packages/humanize/time.py is in python3-humanize 0.5.1-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | #!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Time humanizing functions. These are largely borrowed from Django's
``contrib.humanize``."""
import time
from datetime import datetime, timedelta, date
from .i18n import ngettext, gettext as _
__all__ = ['naturaldelta', 'naturaltime', 'naturalday', 'naturaldate']
def _now():
return datetime.now()
def abs_timedelta(delta):
"""Returns an "absolute" value for a timedelta, always representing a
time distance."""
if delta.days < 0:
now = _now()
return now - (now + delta)
return delta
def date_and_delta(value):
"""Turn a value into a date and a timedelta which represents how long ago
it was. If that's not possible, return (None, value)."""
now = _now()
if isinstance(value, datetime):
date = value
delta = now - value
elif isinstance(value, timedelta):
date = now - value
delta = value
else:
try:
value = int(value)
delta = timedelta(seconds=value)
date = now - delta
except (ValueError, TypeError):
return (None, value)
return date, abs_timedelta(delta)
def naturaldelta(value, months=True):
"""Given a timedelta or a number of seconds, return a natural
representation of the amount of time elapsed. This is similar to
``naturaltime``, but does not add tense to the result. If ``months``
is True, then a number of months (based on 30.5 days) will be used
for fuzziness between years."""
now = _now()
date, delta = date_and_delta(value)
if date is None:
return value
use_months = months
seconds = abs(delta.seconds)
days = abs(delta.days)
years = days // 365
days = days % 365
months = int(days // 30.5)
if not years and days < 1:
if seconds == 0:
return _("a moment")
elif seconds == 1:
return _("a second")
elif seconds < 60:
return ngettext("%d second", "%d seconds", seconds) % seconds
elif 60 <= seconds < 120:
return _("a minute")
elif 120 <= seconds < 3600:
minutes = seconds // 60
return ngettext("%d minute", "%d minutes", minutes) % minutes
elif 3600 <= seconds < 3600 * 2:
return _("an hour")
elif 3600 < seconds:
hours = seconds // 3600
return ngettext("%d hour", "%d hours", hours) % hours
elif years == 0:
if days == 1:
return _("a day")
if not use_months:
return ngettext("%d day", "%d days", days) % days
else:
if not months:
return ngettext("%d day", "%d days", days) % days
elif months == 1:
return _("a month")
else:
return ngettext("%d month", "%d months", months) % months
elif years == 1:
if not months and not days:
return _("a year")
elif not months:
return ngettext("1 year, %d day", "1 year, %d days", days) % days
elif use_months:
if months == 1:
return _("1 year, 1 month")
else:
return ngettext("1 year, %d month",
"1 year, %d months", months) % months
else:
return ngettext("1 year, %d day", "1 year, %d days", days) % days
else:
return ngettext("%d year", "%d years", years) % years
def naturaltime(value, future=False, months=True):
"""Given a datetime or a number of seconds, return a natural representation
of that time in a resolution that makes sense. This is more or less
compatible with Django's ``naturaltime`` filter. ``future`` is ignored for
datetimes, where the tense is always figured out based on the current time.
If an integer is passed, the return value will be past tense by default,
unless ``future`` is set to True."""
now = _now()
date, delta = date_and_delta(value)
if date is None:
return value
# determine tense by value only if datetime/timedelta were passed
if isinstance(value, (datetime, timedelta)):
future = date > now
ago = _('%s from now') if future else _('%s ago')
delta = naturaldelta(delta, months)
if delta == _("a moment"):
return _("now")
return ago % delta
def naturalday(value, format='%b %d'):
"""For date values that are tomorrow, today or yesterday compared to
present day returns representing string. Otherwise, returns a string
formatted according to ``format``."""
try:
value = date(value.year, value.month, value.day)
except AttributeError:
# Passed value wasn't date-ish
return value
except (OverflowError, ValueError):
# Date arguments out of range
return value
delta = value - date.today()
if delta.days == 0:
return _('today')
elif delta.days == 1:
return _('tomorrow')
elif delta.days == -1:
return _('yesterday')
return value.strftime(format)
def naturaldate(value):
"""Like naturalday, but will append a year for dates that are a year
ago or more."""
try:
value = date(value.year, value.month, value.day)
except AttributeError:
# Passed value wasn't date-ish
return value
except (OverflowError, ValueError):
# Date arguments out of range
return value
delta = abs_timedelta(value - date.today())
if delta.days >= 365:
return naturalday(value, '%b %d %Y')
return naturalday(value)
|