MCPcopy
hub / github.com/django/django / timesince

Function timesince

django/utils/timesince.py:28–135  ·  view source on GitHub ↗

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 ta

(d, now=None, reversed=False, time_strings=None, depth=2)

Source from the content-addressed store, hash-verified

26
27
28def timesince(d, now=None, reversed=False, time_strings=None, depth=2):
29 """
30 Take two datetime objects and return the time between d and now as a nicely
31 formatted string, e.g. "10 minutes". If d occurs after now, return
32 "0 minutes".
33
34 Units used are years, months, weeks, days, hours, and minutes.
35 Seconds and microseconds are ignored.
36
37 The algorithm takes into account the varying duration of years and months.
38 There is exactly "1 year, 1 month" between 2013/02/10 and 2014/03/10,
39 but also between 2007/08/10 and 2008/09/10 despite the delta being 393 days
40 in the former case and 397 in the latter.
41
42 Up to `depth` adjacent units will be displayed. For example,
43 "2 weeks, 3 days" and "1 year, 3 months" are possible outputs, but
44 "2 weeks, 3 hours" and "1 year, 5 days" are not.
45
46 `time_strings` is an optional dict of strings to replace the default
47 TIME_STRINGS dict.
48
49 `depth` is an optional integer to control the number of adjacent time
50 units returned.
51
52 Originally adapted from
53 https://web.archive.org/web/20060617175230/http://blog.natbat.co.uk/archive/2003/Jun/14/time_since
54 Modified to improve results for years and months.
55 """
56 if time_strings is None:
57 time_strings = TIME_STRINGS
58 if depth <= 0:
59 raise ValueError("depth must be greater than 0.")
60 # Convert datetime.date to datetime.datetime for comparison.
61 if not isinstance(d, datetime.datetime):
62 d = datetime.datetime(d.year, d.month, d.day)
63 if now and not isinstance(now, datetime.datetime):
64 now = datetime.datetime(now.year, now.month, now.day)
65
66 # Compared datetimes must be in the same time zone.
67 if not now:
68 now = datetime.datetime.now(d.tzinfo if is_aware(d) else None)
69 elif is_aware(now) and is_aware(d):
70 now = now.astimezone(d.tzinfo)
71
72 if reversed:
73 d, now = now, d
74 delta = now - d
75
76 # Ignore microseconds.
77 since = delta.days * 24 * 60 * 60 + delta.seconds
78 if since <= 0:
79 # d is in the future compared to now, stop processing.
80 return avoid_wrapping(time_strings["minute"] % {"num": 0})
81
82 # Get years and months.
83 total_months = (now.year - d.year) * 12 + (now.month - d.month)
84 if d.day > now.day or (d.day == now.day and d.time() > now.time()):
85 total_months -= 1

Calls 7

is_awareFunction · 0.90
avoid_wrappingFunction · 0.90
gettextFunction · 0.90
timeMethod · 0.80
nowMethod · 0.45
appendMethod · 0.45
joinMethod · 0.45