/usr/share/cagefs-skeleton/usr/local/lib/python3.9/site-packages/django/utils
import datetime from django.utils.html import avoid_wrapping from django.utils.timezone import is_aware from django.utils.translation import gettext, ngettext_lazy TIME_STRINGS = { "year": ngettext_lazy("%(num)d year", "%(num)d years", "num"), "month": ngettext_lazy("%(num)d month", "%(num)d months", "num"), "week": ngettext_lazy("%(num)d week", "%(num)d weeks", "num"), "day": ngettext_lazy("%(num)d day", "%(num)d days", "num"), "hour": ngettext_lazy("%(num)d hour", "%(num)d hours", "num"), "minute": ngettext_lazy("%(num)d minute", "%(num)d minutes", "num"), } TIME_STRINGS_KEYS = list(TIME_STRINGS.keys()) TIME_CHUNKS = [ 60 * 60 * 24 * 7, # week 60 * 60 * 24, # day 60 * 60, # hour 60, # minute ] MONTHS_DAYS = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31) def timesince(d, now=None, reversed=False, time_strings=None, depth=2): """ Take two datetime objects and return the time between d and now as a nicely formatted string, e.g. "10 minutes". If d occurs after now, return "0 minutes". Units used are years, months, weeks, days, hours, and minutes. Seconds and microseconds are ignored. The algorithm takes into account the varying duration of years and months. There is exactly "1 year, 1 month" between 2013/02/10 and 2014/03/10, but also between 2007/08/10 and 2008/09/10 despite the delta being 393 days in the former case and 397 in the latter. Up to `depth` adjacent units will be displayed. For example, "2 weeks, 3 days" and "1 year, 3 months" are possible outputs, but "2 weeks, 3 hours" and "1 year, 5 days" are not. `time_strings` is an optional dict of strings to replace the default TIME_STRINGS dict. `depth` is an optional integer to control the number of adjacent time units returned. Originally adapted from https://web.archive.org/web/20060617175230/http://blog.natbat.co.uk/archive/2003/Jun/14/time_since Modified to improve results for years and months. """ if time_strings is None: time_strings = TIME_STRINGS if depth <= 0: raise ValueError("depth must be greater than 0.") # Convert datetime.date to datetime.datetime for comparison. if not isinstance(d, datetime.datetime): d = datetime.datetime(d.year, d.month, d.day) if now and not isinstance(now, datetime.datetime): now = datetime.datetime(now.year, now.month, now.day) # Compared datetimes must be in the same time zone. if not now: now = datetime.datetime.now(d.tzinfo if is_aware(d) else None) elif is_aware(now) and is_aware(d): now = now.astimezone(d.tzinfo) if reversed: d, now = now, d delta = now - d # Ignore microseconds. since = delta.days * 24 * 60 * 60 + delta.seconds if since <= 0: # d is in the future compared to now, stop processing. return avoid_wrapping(time_strings["minute"] % {"num": 0}) # Get years and months. total_months = (now.year - d.year) * 12 + (now.month - d.month) if d.day > now.day or (d.day == now.day and d.time() > now.time()): total_months -= 1 years, months = divmod(total_months, 12) # Calculate the remaining time. # Create a "pivot" datetime shifted from d by years and months, then use # that to determine the other parts. if years or months: pivot_year = d.year + years pivot_month = d.month + months if pivot_month > 12: pivot_month -= 12 pivot_year += 1 pivot = datetime.datetime( pivot_year, pivot_month, min(MONTHS_DAYS[pivot_month - 1], d.day), d.hour, d.minute, d.second, tzinfo=d.tzinfo, ) else: pivot = d remaining_time = (now - pivot).total_seconds() partials = [years, months] for chunk in TIME_CHUNKS: count = int(remaining_time // chunk) partials.append(count) remaining_time -= chunk * count # Find the first non-zero part (if any) and then build the result, until # depth. i = 0 for i, value in enumerate(partials): if value != 0: break else: return avoid_wrapping(time_strings["minute"] % {"num": 0}) result = [] current_depth = 0 while i < len(TIME_STRINGS_KEYS) and current_depth < depth: value = partials[i] if value == 0: break name = TIME_STRINGS_KEYS[i] result.append(avoid_wrapping(time_strings[name] % {"num": value})) current_depth += 1 i += 1 return gettext(", ").join(result) def timeuntil(d, now=None, time_strings=None, depth=2): """ Like timesince, but return a string measuring the time until the given time. """ return timesince(d, now, reversed=True, time_strings=time_strings, depth=depth)
.
Edit
..
Edit
__init__.py
Edit
__pycache__
Edit
_os.py
Edit
archive.py
Edit
asyncio.py
Edit
autoreload.py
Edit
baseconv.py
Edit
cache.py
Edit
connection.py
Edit
crypto.py
Edit
datastructures.py
Edit
dateformat.py
Edit
dateparse.py
Edit
dates.py
Edit
datetime_safe.py
Edit
deconstruct.py
Edit
decorators.py
Edit
deprecation.py
Edit
duration.py
Edit
encoding.py
Edit
feedgenerator.py
Edit
formats.py
Edit
functional.py
Edit
hashable.py
Edit
html.py
Edit
http.py
Edit
inspect.py
Edit
ipv6.py
Edit
itercompat.py
Edit
jslex.py
Edit
log.py
Edit
lorem_ipsum.py
Edit
module_loading.py
Edit
numberformat.py
Edit
regex_helper.py
Edit
safestring.py
Edit
termcolors.py
Edit
text.py
Edit
timesince.py
Edit
timezone.py
Edit
topological_sort.py
Edit
translation
Edit
tree.py
Edit
version.py
Edit
xmlutils.py
Edit