time difference inflected as before/after
I'd like to see a feature like the following:
>>> p.date_diff(datetime.timedelta(minutes=-30))
'00:30:00 before'
>>> p.date_diff(5)
'00:00:05 after'
>>> p.date_diff(0)
'at'
I would expect one to use the result to produce nice output for a time difference like:
Your flight departed 00:00:05 after its scheduled departure.
It would be nice if it accepted a time formatter such that it could alternately emit:
>>> p.date_diff(datetime.timedelta(minutes=-30), fmt=nice_time)
'30 minutes before'
>>> p.date_diff(5, fmt=nice_time)
'five seconds after'
>>> p.date_diff(0, fmt=nice_time)
'at'
Perhaps that inflection is too trivial for a library like inflect. Or perhaps there are nuances I haven't yet considered.
The timeago package will format a datetime object as a "X time ago" statement.
It might also be useful to be able to convert a timedelta, or time in seconds, to a natural language time string.
Cribbing StackOverflow, here's a simple converter from seconds to a natural time, but it might make more sense to base something around a timedelta object?
#https://stackoverflow.com/a/24542445/454773
intervals = (
('weeks', 604800), # 60 * 60 * 24 * 7
('days', 86400), # 60 * 60 * 24
('hours', 3600), # 60 * 60
('minutes', 60),
('seconds', 1),
)
def display_time(seconds, granularity=3, sep=',', andword='and'):
"""Take a time in seconds and return a sensible
natural language interpretation of it."""
def nl_join(l):
if len(l)>2:
return ', '.join(f'{l[:-1]} {andword} {str(l[-1])}')
elif len(l)==2:
return f' {andword} '.join(l)
return l[0]
result = []
for name, count in intervals:
value = seconds // count
if value:
seconds -= value * count
if value == 1:
name = name.rstrip('s')
result.append("{} {}".format(value, name))
return nl_join(result[:granularity])