import datetime from django.utils.translation import npgettext, pgettext, ungettext def nice_repr(timedelta, display='long', sep=', '): """ Turns a datetime.timedelta object into a nice string repr. display can be 'minimal', 'short' or 'long' [default]. >>> from datetime import timedelta as td >>> nice_repr(td(days=1, hours=2, minutes=3, seconds=4)) '1 day, 2 hours, 3 minutes, 4 seconds' >>> nice_repr(td(days=1, seconds=1), 'minimal') '1d, 1s' """ assert isinstance(timedelta, datetime.timedelta), 'First argument must be a timedelta.' result = [] weeks = timedelta.days // 7 days = timedelta.days % 7 hours = timedelta.seconds // 3600 minutes = (timedelta.seconds % 3600) // 60 seconds = timedelta.seconds % 60 if display == 'simple-no-seconds': days += weeks * 7 if days: if hours or minutes: return '%d day%s %d:%02d' % (days, 's'[days == 1:], hours, minutes) return '%d day%s' % (days, 's'[days == 1:]) else: return '%d:%02d' % (hours, minutes) elif display == 'sql': days += weeks * 7 return '%d %02d:%02d:%02d' % (days, hours, minutes, seconds) elif display == 'simple': days += weeks * 7 if days: return '%d day%s %02d:%02d:%02d' % (days, 's'[days == 1:], hours, minutes, seconds) else: return '%02d:%02d:%02d' % (hours, minutes, seconds) elif display == 'localized': days += weeks * 7 if days: return npgettext('time format with day', '%d day %h:%m:%s', '%d days %h:%m:%s', days) \ .replace('%d', str(days)).replace('%h', '%02d' % hours).replace('%m', '%02d' % minutes) \ .replace('%s', '%02d' % seconds) else: return pgettext('time format without day', '%h:%m:%s') \ .replace('%h', '%02d' % hours).replace('%m', '%02d' % minutes).replace('%s', '%02d' % seconds) elif display == 'localized-no-seconds': days += weeks * 7 if days: if hours or minutes: return npgettext('time format no seconds with day', '%d day %h:%m', '%d days %h:%m', days) \ .replace('%d', str(days)).replace('%h', '%02d' % hours).replace('%m', '%02d' % minutes) return ungettext('%d day', '%d days', days) % days else: return pgettext('hours and minutes', '%h:%m').replace('%h', '%02d' % hours).replace('%m', '%02d' % minutes) elif display == 'concise': days += weeks * 7 if days: return '%dd %02d:%02d:%02d' % (days, hours, minutes, seconds) else: return '%02d:%02d:%02d' % (hours, minutes, seconds) elif display == 'noday': days += weeks * 7 hours += days * 24 return '%02d:%02d:%02d' % (hours, minutes, seconds) elif display == 'minimal': words = ['w', 'd', 'h', 'm', 's'] elif display == 'short': words = [' wks', ' days', ' hrs', ' min', ' sec'] else: words = [' weeks', ' days', ' hours', ' minutes', ' seconds'] values = [weeks, days, hours, minutes, seconds] for i in range(len(values)): if values[i]: if values[i] == 1 and len(words[i]) > 1: result.append('%i%s' % (values[i], words[i].rstrip('s'))) else: result.append('%i%s' % (values[i], words[i])) return sep.join(result)