alexferl
alexferl

Reputation: 627

"TypeError: must be string, not datetime.datetime" in Jinja2 template when using strftime

I'm trying to format dates generated with datetime.datetime.utcnow() (using this because it's the equivalent of ISODate() in MongoDB which is the database my app uses) in my Flask application but Jinja2 won't render them.

I have the following function in my app:

def format_isodate(timestamp):
    """Format a ISODate time stamp for display."""
    date = datetime.datetime.strptime(timestamp, "%Y-%m-%d %H:%M:%S.%f")
    return date.strftime('%Y-%m-%d @ %H:%M:%S')

The dates look like this:

"2013-07-04 20:06:05.088000"

And I have the following filter:

app.jinja_env.filters['isodateformat'] = format_isodate

But when I try to format the timestamp in templates:

{{ change.submit_date|isodateformat }}

I get this error:

"TypeError: must be string, not datetime.datetime"

I don't understand why I am getting this error. Doesn't strftime() convert dates to string?

Upvotes: 2

Views: 11562

Answers (1)

andrewdotn
andrewdotn

Reputation: 34833

The problem is that utcnow() returns a datetime.datetime object, not a string. If you check the line number in the exception, it’s likely the strptime call that’s failing—it can parse a string into a date, but it can’t parse a date.

Example:

#!/usr/bin/env python2.7

import datetime

import jinja2

def format_isodate(timestamp):
    """Format a ISODate time stamp for display."""
    date = datetime.datetime.strptime(timestamp, "%Y-%m-%d %H:%M:%S.%f")
    return date.strftime('%Y-%m-%d @ %H:%M:%S')

e = jinja2.Environment()
e.filters['isodateformat'] = format_isodate

t = e.from_string('{{ change.submit_date|isodateformat }}')
print t.render(change={'submit_date': "2013-07-04 20:06:05.088000"})
print t.render(change={'submit_date': datetime.datetime.now()})

The first print of a string succeeds, but the second one fails with TypeError: must be string, not datetime.datetime.

Upvotes: 4

Related Questions