This is a filter that takes a datetime instance and returns a "time since" string. For example, "3 minutes ago" or "4 weeks ago":
from datetime import datetime
@app.template_filter()
def timesince(dt, default="just now"):
"""
Returns string representing "time since" e.g.
3 days ago, 5 hours ago etc.
"""
now = datetime.utcnow()
diff = now - dt
periods = (
(diff.days / 365, "year", "years"),
(diff.days / 30, "month", "months"),
(diff.days / 7, "week", "weeks"),
(diff.days, "day", "days"),
(diff.seconds / 3600, "hour", "hours"),
(diff.seconds / 60, "minute", "minutes"),
(diff.seconds, "second", "seconds"),
)
for period, singular, plural in periods:
if period:
return "%d %s ago" % (period, singular if period == 1 else plural)
return default
Further enhancement would include localization support for the various strings and a "timeuntil" filter that returns e.g. "3 minutes from now".
This snippet by Dan Jacob can be used freely for anything you like. Consider it public domain.
Comments
This should handle both past and present by Sean Vieira on 2010-07-19 @ 18:01
from datetime import datetime
@app.template_filter() def friendly_time(dt, past_="ago", future_="from now", default="just now"): """ Returns string representing "time since" or "time until" e.g. 3 days ago, 5 hours from now etc. """
now = datetime.utcnow() if now > dt: diff = now - dt dt_is_past = True else: diff = dt - now dt_is_past = False
periods = ( (diff.days / 365, "year", "years"), (diff.days / 30, "month", "months"), (diff.days / 7, "week", "weeks"), (diff.days, "day", "days"), (diff.seconds / 3600, "hour", "hours"), (diff.seconds / 60, "minute", "minutes"), (diff.seconds, "second", "seconds"), )
for period, singular, plural in periods:
if period: return "%d %s %s" % (period, \ singular if period == 1 else plural, \ past_ if dt_is_past else future_)
return default
Hopefully this preserves formating properly by Sean Vieira on 2010-07-19 @ 18:03
@app.template_filter() def friendly_time(dt, past_="ago", future_="from now", default="just now"): """ Returns string representing "time since" or "time until" e.g. 3 days ago, 5 hours from now etc. """
now = datetime.utcnow() if now > dt: diff = now - dt dt_is_past = True else: diff = dt - now dt_is_past = False
periods = ( (diff.days / 365, "year", "years"), (diff.days / 30, "month", "months"), (diff.days / 7, "week", "weeks"), (diff.days, "day", "days"), (diff.seconds / 3600, "hour", "hours"), (diff.seconds / 60, "minute", "minutes"), (diff.seconds, "second", "seconds"), )
for period, singular, plural in periods:
if period: return "%d %s %s" % (period, \ singular if period == 1 else plural, \ past_ if dt_is_past else future_)
return default
Blast! by Sean Vieira on 2010-07-19 @ 18:04
Well, that's twice now -- if someone who knows could update the above to be properly formatted, that would be greatly appreciated!
This should handle both past and present by Sean Vieira on 2010-07-19 @ 18:10
Apologies for the multiple submits above -- unfortunately the warning that comments should be formatted with Creole is only in the Create new snippets page, and I only saw it after I went digging.
How would you apply this to template? by Delilah on 2012-02-14 @ 05:07
The template code would be helpful here as well.
Humanize implementation by Sergey Prokhorov on 2013-05-17 @ 23:44
This can be acchieved using humanize library. Example:
{{{ #!python import humanize from flask.ext import babel
@app.template_filter() def naturaltime(datetime): locale = babel.get_locale() locale_name = '_'.join([locale.language, locale.territory]) humanize.activate(locale_name) return humanize.naturaltime(datetime) }}}
Humanize implementation by Sergey Prokhorov on 2013-05-17 @ 23:45
This can be acchieved using humanize library. Example: