def humanreadable_timedelta(
theDateAndTime,
precise=False,
complete=False,
fromDate=None):
if not theDateAndTime:
return ""
if not fromDate:
fromDate = datetime.now(timezone.utc)
if theDateAndTime > fromDate:
return None
elif theDateAndTime == fromDate:
return _('now')
delta = fromDate - theDateAndTime
'''
the timedelta structure does not have all units; bigger units are converted
into smaller ones (hours -> seconds, minutes -> seconds, weeks > days, ...)
but we need all units:
'''
deltaMinutes = delta.seconds // 60
deltaHours = delta.seconds // 3600
deltaYears = delta.days // 365
deltaMonths = delta.days // 30
deltaMinutes -= deltaHours * 60
deltaWeeks = delta.days // 7
deltaSeconds = delta.seconds - deltaMinutes * 60 - deltaHours * 3600
deltaDays = delta.days - deltaWeeks * 7
deltaMilliSeconds = delta.microseconds // 1000
deltaMicroSeconds = delta.microseconds - deltaMilliSeconds * 1000
valuesAndNames = [
(deltaYears, _('year')),
(deltaMonths, _('month')),
(deltaWeeks, _('week')),
(deltaDays, _('day')),
(deltaHours, _('hour')),
(deltaMinutes, _('minute')),
(deltaSeconds, _('second'))
]
if precise:
valuesAndNames.append((deltaMilliSeconds, _('millisecond')))
valuesAndNames.append((deltaMicroSeconds, _('microsecond')))
text = ""
for value, name in valuesAndNames:
if complete:
if value > 0:
text += len(text) and ", " or ""
text += "%d %s" % (value, name)
text += (value > 1) and "s" or ""
else:
if value > 0:
text += "%d %s" % (value, name)
text += (value > 1) and "s" or ""
break
# replacing last occurrence of a comma by an 'and'
if text.find(",") > 0:
text = " and ".join(text.rsplit(", ", 1))
return text