Johnny Nguyen
Johnny Nguyen

Reputation: 21

Formating "posted x seconds ago" in Jinja 2(Flask) with strftime?

I'd like to make my code a little more user-friendly such that when users post something, i'd like it to say "x seconds/hour/day ago"

so far my code is

{{ post.date_posted.strftime('%Y-%m-%d %H:%M:%S') }}

Upvotes: 2

Views: 2181

Answers (2)

James_SO
James_SO

Reputation: 1387

Given a requirement to make the output more user-friendly, and assuming the use of Flask and jinja, and assuming a blueprint called some_blueprint, we can do a custom filter function in your Flask controller like this:

@some_blueprint.app_template_filter()
def whendat(date_obj):
    formatString = "Whenever"
    retValMins = (datetime.today() - date_obj).total_seconds()/60
    if retValMins < 0:
        # Future
        formatString = "{:,.0f} minutes from now".format(abs(retValMins))
    else:
        formatString = "{:,.0f} minutes ago".format(retValMins)
    if abs(retValMins) > 120:
        # Use Hours if minutes > 120
        retValHours = (datetime.today() - date_obj).total_seconds()/60/60
        if retValHours < 0:
            # Future
            formatString = "{:,.0f} hours from now".format(abs(retValHours))
        else:
            formatString = "{:,.0f} hours ago".format(retValHours)
        if abs(retValHours) > 48:
            # Use Days if hours > 48
            retValDays = (datetime.today() - date_obj).days
            print(retValDays)
            if retValDays < 0:
                # Future
                formatString = "{:,.0f} days from now".format(abs(retValDays))
            else:
                formatString = "{:,.0f} days ago".format(retValDays)
    return formatString

In your Jinja template, use like so:

{{ record.SomeDtTm | whendat }}

Obviously you can pick your own thresholds for when to switch units. You can also modify the format string to add a decimal, but to help a user quickly identify the age of something, the simpler the better. (you can always show the full timestamp elsewhere)

Upvotes: 0

UtahJarhead
UtahJarhead

Reputation: 2217

You want datetime.timedelta()

import datetime
import time

old_time = datetime.datetime.now()
time.sleep(20)
new_time = datetime.datetime.now()

# The below line returns a 'timedelta' object.
delta = new_time - old_time

print('{} seconds have passed.'.format(delta.total_seconds()))

# or
print(
    '{} days, {} hours, {} minutes, {} seconds passed.'.format(
        delta.days,
        delta.seconds//3600,
        (delta.seconds//60)%60,
        int(delta.total_seconds()%60)))

I believe it also exists for just date and time modules as well.

Upvotes: 1

Related Questions