ago/ago.py
RussellBallestrini c1991cd380 Reverted back to using a counter 'count' to keep track of precision.
Using our own counter, opposed to enumerates, allows us to skip increment::

 if d[ unit ] == 0: continue # skip 0's

The continue moves us back to the top of the loop, and which bypasses count += 1.  This allows us to have a datetime/timedelta that has a 0 value for a unit, and it will not effect precision fufillment.

For example, review this test::

 ONE_YEAR_FOUR_HOURS_DELTA = timedelta( 365, 14400, 0 )

 def test_zero_day_is_skipped_display_hour():
     _result = human( ONE_YEAR_FOUR_HOURS_DELTA, precision = 2 )
     assert 'year' in _result
     # day is 0 so it is skipped, so we should show hours ...
     assert 'hour' in _result

This test will fail using enumerate or using a slice on the units[:precision] tuple.
2013-05-23 09:42:39 -04:00

38 lines
1.2 KiB
Python

from datetime import datetime
from datetime import timedelta
def delta2dict( delta ):
"""Accepts a delta, returns a dictionary of units"""
delta = abs( delta )
return {
'year' : delta.days / 365 ,
'day' : delta.days % 365 ,
'hour' : delta.seconds / 3600 ,
'minute' : (delta.seconds / 60) % 60 ,
'second' : delta.seconds % 60 ,
'microsecond' : delta.microseconds
}
def human(dt, precision=2, past_tense='{} ago', future_tense='in {}'):
"""Accept a datetime or timedelta, return a human readable delta string"""
delta = dt
if type(dt) is not type(timedelta()):
delta = datetime.now() - dt
the_tense = past_tense
if delta < timedelta(0):
the_tense = future_tense
d = delta2dict( delta )
hlist = []
count = 0
units = ( 'year', 'day', 'hour', 'minute', 'second', 'microsecond' )
for unit in units:
if count >= precision: break # met precision
if d[ unit ] == 0: continue # skip 0's
s = '' if d[ unit ] == 1 else 's' # handle plurals
hlist.append( '%s %s%s' % ( d[unit], unit, s ) )
count += 1
human_delta = ', '.join( hlist )
return the_tense.format(human_delta)