"TypeError: must be string, not datetime.datetime" in Jinja2 template when using strftime
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
.
alexferl
Updated on June 04, 2022Comments
-
alexferl almost 2 years
I'm trying to format dates generated with
datetime.datetime.utcnow()
(using this because it's the equivalent ofISODate()
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? -
alexferl almost 11 yearsThank you! I understand now. I inserted my date with datetime.datetime.utcnow() which MongoDB via PyMongo understood is a date object (ISODate()) so it saved it as a date object. So when I query the document for the date, I get a date object returned to me as well. For the record, I fixed it by replacing the last two rows of my function with this line:
return timestamp.replace(tzinfo=pytz.utc).strftime("%Y-%m-%d @ %H:%M:%S")