Flask - Flask-Moment gives out an error: AttributeError: 'str' object has no attribute 'strftime' - datetime

Ok, so i want to change a datetime value from mysql database into a desired format. so my code goes:
file: app.py
from flask import Flask, render_template, flash, redirect, url_for, session, request, logging
from datetime import datetime
from flask_moment import Moment
app = Flask(__name__)
moment = Moment(app)
mysql = MySQL(cursorclass=DictCursor)
#app.route('/users')
def users():
# create cursor
cur = mysql.get_db().cursor()
# execute query
cur.execute('SELECT * FROM users')
# get results
users = cur.fetchall()
return render_template('users.html', title = 'User Accounts', users=users)
then on my users.html, i display the datetime value on a table which goes:
file: users.html
<tbody>
{% for row in users %}
<tr>
<td>{{row.id}}</td>
<td>{{row.username}}</td>
<td>{{row.fullname}}</td>
<td>{{moment(row.created_at).format('LLL')}}</td> # this causes an error
</tr>
{% endfor %}
</tbody>
But when i put in the following code for the datetime:
<td>{{moment().format('LLL')}}</td> # this is working
So in short,
# this is not working
# Causes an "AttributeError: 'str' object has no attribute 'strftime'" error
moment(row.created_at).format('LLL')
# this is working
# but i can't modify the data based on the value from mysql database
moment().format('LLL')
# by the way, this is also not working
# and it also causes the same error
row.created_at.strftime('%M %d, %Y')
What i need to know is how to format datetime value in the flask template and Flask-Moment seems to be the only way

EDIT:
You can also try using:
{{ row.created_at.strftime('%M %d, %Y') }}
or the jinja datetime filter:
{{ row.created_at|datetime }}
ORIGINAL ANSWER:
It appears you need to convert from MySQL DateTime to Python datetime. Without seeing more of your code, maybe something like this would work, though there is probably a more efficient way:
# get results
users = cur.fetchall()
for user in users:
user.created_at = datetime.strptime(user.created_at, '%Y-%M-%d') # you have to use the mysql format here
return render_template('users.html', title = 'User Accounts', users=users)
You are using strftime when it appears that python is interpreting the MySQL datetime as a string, not a datetime() object, so you have to use strptime

Momentjs couldn't parse it because it is an 'str'. Use datetime to parse the string before passing it to the momentjs object e.g
from datetime import datetime
row_created_at = datetime.strptime(row_created_at, %m %d,%Y ')
then pass it to the momentjs object like so
{{moment(row_created).format("LLL")}}
That should do the trick

Related

How can I set execution date in HttpSensor (Airflow)?

I try to pass execution date to httpsensor operator.
is_api_available = HttpSensor(
task_id='is_api_available',
http_conn_id='data_available',
endpoint='api/3/action/date= {{I want to set date in here}}'
)
I can get execution date parameter in python operator like this:
print("my start date : ",kwargs['execution_date'] )
it works but how can I get it in other operators?
thanks in advance
You can use Jinja template with the variable {{ ds }}, it format the datetime as YYYY-MM-DD
for more macros you can see at https://airflow.apache.org/docs/apache-airflow/stable/templates-ref.html
is_api_available = HttpSensor(
task_id='is_api_available',
http_conn_id='data_available',
endpoint='api/3/action/date={{ ds }}')
api/3/action/date=2022-06-25

"Value 0:00:00.416559 has unexpected type <class 'datetime.timedelta'>" when diff of two timestamps as value in jsonPayload gcloud logger.log_struct()

Code:
from datetime import datetime
start = datetime.now()
sleep(1)
diff = datetime.now() - start
When saving the diff variable as a value of a dictionary "my_dict" that will then be written to a jsonPayload output by the google cloud logging module with its function log_struct(my_dict), I get:
Value 0:00:00.416559 has unexpected type <class 'datetime.timedelta'>
How to get the format as seconds instead to get rid of the datatype error?
Change to:
diff = (datetime.now() - start).total_seconds()
Taken from Python finding difference between two time stamps in minutes.

Datetime object into readable format Jinja

I am trying to format a datetime value into a human readable format
For example:
value = 2019-12-17T08:12:58.472+00:00
expected result = 17/12/2019.
The code has to be in Jinja. Been trying to do the following, but getting an error message:
{{ 2019-12-17T08:12:58.472+00:00 | from.strftime('%Y-%m-%d') }}
Can anybody help?
This works for me to pull out a date in your requested "human readable" format %d/%m/%Y:
>>> from jinja2 import Template
>>> from datetime import datetime
>>> t = Template("Hello, {{ your_jinja_date_var.strftime('%d/%m/%Y') }}!")
>>> t.render(your_jinja_date_var=datetime.now())
'Hello, 17/12/2019!'
Here are the API docs where you can find other incredible features of jinja.
Your strftime function from your question above does imply standard ISO date conventions %Y-%m-%d. If you'd like that date format:
>>> t = Template("Hello, {{ your_jinja_date_var.strftime('%Y-%m-%d') }}!")
>>> t.render(your_jinja_date_var=datetime.now())
'Hello, 2019-12-17!'
And to top it off, here's a nice tutorial article on the topic which I found useful, from the Real Python platform.
<p>Last seen: {{ user.last_seen.strftime('%d-%m-%Y, %T') }}</p>
This worked for me for Date and Time both.

How to do timestamp to DateTime conversion in laravel 5

How can i change the timestamp format into dateTime format in laravel 5, while fetching the timestamp from the table.?
<td>{{ $nam->date("Y-m-d H:i:s", lastLoginTime) }}</td>
When I tried this one, its showing error "Call to undefined method stdClass::date()".
Anyone help me to solve it.
In the Model you can add the below function to add dates to diffForHumans() function:
funtion getDates()
{
return array('created_at', 'updated_at', 'lastLoginTime');
}
etc etc.
Or you can use the following:
{{ $nam->lastLoginTime->format('Y-m-d H:i:s') }}

Specify DateTime format on zope.schema.Date on Plone

I'm working on a form with Formlib that looks like this:
from zope.schema import Choice, Float, Int, Date, TextLine
from Products.Five.formlib.formbase import PageForm
class ISimuladorForm(Interface):
"""
Zope Interface for the financial simulator for sofomanec.
"""
start_date = Date(title=_(u'Start Date'),
description=_(u'Loan start date.'),
required=False)
.
.
.
class SimuladorForm(PageForm):
form_fields = form.FormFields(ISimuladorForm)
The default input format for start_date is "mm/dd/yy", but users need to input the start_date in this format: "dd/mm/yy".
How do I change the default Date format for this Interface/Schema/Form?
You can use the DateI18nWidget instead of the default DateWidget.
It takes a displayStyle attribute that controls the formatting of the value, and it'll use the request locale to format the date. displayStyle must be one of 'full', 'long', 'medium', 'short', or None and refers to the date formats defined in zope.i18n; the default is None, which I think means 'short' but this is unclear from the code.
The exact formatting is taken from the request locale, which in turn is based on the language set for the Plone site by the portal_languages tool. Thus setting the language of the site also determines what date formats the DateI18nWidget will use; these are defined in the zope.i18n package in the locales/data directory, in a set of XML files (look for the <dateFormats> element).
If this isn't satisfactory then you'll have to create a custom browser widget. Your best bet is to subclass the DateWidget yourself and provide a new _toFormValue method to format the dates the way you want.
This might be helpful to add a custom date widget to your formlib form:
http://plone.org/documentation/manual/developer-manual/forms/using-zope.formlib/customizing-the-template-and-the-widgets
I suggest to write your own date widget by deriving from one of the existing
date widget classes:
http://svn.zope.org/zope.formlib/trunk/src/zope/formlib/textwidgets.py?rev=113031&view=markup
A custom conversion of the date format using the
_toFieldValue()
_fromFieldValue()
hooks is pretty easy...look at the existing code.
This is what I did:
from zope.app.form.browser import DateI18nWidget
from zope.i18n.format import DateTimeParseError
from zope.app.form.interfaces import ConversionError
class MyDateI18nWidget(DateI18nWidget):
displayStyle = None
def _toFieldValue(self, input):
if input == self._missing:
return self.context.missing_value
else:
try:
formatter = self.request.locale.dates.getFormatter(
self._category, (self.displayStyle or None))
return formatter.parse(input.lower())
except (DateTimeParseError, ValueError), v:
raise ConversionError(_("Invalid datetime data"),
"%s (%r)" % (v, input))
class SimuladorForm(PageForm):
...
form_fields['start_date'].custom_widget = MyDateI18nWidget

Resources