ago/ago.py
russellballestrini 36102bba88 fix millisecs versus microsecs
changed ago.py
changed setup.py
changed test_ago.py
2017-10-14 20:49:50 -04:00

72 lines
2.4 KiB
Python

from datetime import (
datetime,
timedelta,
)
units = ('year', 'day', 'hour', 'minute', 'second', 'millisecond', 'microsecond')
def get_delta_from_subject(subject):
subject_type = type(subject)
if subject_type is timedelta:
delta = subject
else:
if subject_type is int or subject_type is float:
dt = datetime.fromtimestamp(float(subject))
else:
# assume subject is a datetime object and strip timezone data.
dt = subject.replace(tzinfo=None)
# finally, create a timedelta from datetime.
delta = datetime.now() - dt
return delta
def delta2dict(delta):
"""Accepts a delta, returns a dictionary of units"""
delta = abs(delta)
return {
'year' : int(delta.days / 365),
'day' : int(delta.days % 365),
'hour' : int(delta.seconds / 3600),
'minute' : int(delta.seconds / 60) % 60,
'second' : delta.seconds % 60,
'millisecond' : delta.microseconds/1000,
'microsecond' : delta.microseconds%1000,
}
def human(subject, precision=2, past_tense='{} ago', future_tense='in {}', abbreviate=False):
"""
Accept a subject, return a human readable timedelta string.
:param subject: a datetime, timedelta, or timestamp (integer / float) object
:param precision: the desired amount of unit precision (default: 2)
:param past_tense: the format string used for a past timedelta (default: '{} ago')
:param future_tense: the format string used for a future timedelta (default: 'in {}')
:param abbreviate: boolean to abbreviate units (default: False)
:returns: Human readable timedelta string (Str)
"""
delta = get_delta_from_subject(subject)
the_tense = future_tense if delta < timedelta(0) else past_tense
d = delta2dict( delta )
hlist = []
count = 0
# start building up the output in the hlist.
for unit in units:
if count >= precision: break # met precision
if d[ unit ] == 0: continue # skip 0's
if abbreviate:
if unit == 'millisecond':
abr = 'ms'
elif unit == 'microsecond':
abr = 'um'
else:
abr = unit[0]
hlist.append('{}{}'.format(d[unit], abr))
else:
s = '' if d[ unit ] == 1 else 's' # handle plurals
hlist.append('{} {}{}'.format(d[unit], unit, s))
count += 1
return the_tense.format(', '.join(hlist))