Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert time values inside jinja code to the browser's local timezone when the page loads?

I have a list of flask generated time values in this format: YYYY-DD-MM hh:mm:ss. These time values work as url links and are displayed in my html file using jinja2 like so:

{% for job in jobs %}
    <a href=”{{ url_for(‘jobs/by_id’,job_id=job.job_id) }}">
    {{ job.finishtime }}              #this is the time value
    </a>
{% endfor %}

I want these time values to be automatically converted to the browser's local timezone. I tried using the flask-moment extension but after following all instructions and using {{ moment(job.finishtime).format('MMMM Do YYYY, h:mm:ss a') }}, the time disapppers from the html page when I load it. I tried other moment functions as well but keep getting errors.

Is there a better way to make moment.js talk to my jinja code?

I was hoping not to have to deal with python datetime.

like image 816
Grr4 Avatar asked Nov 09 '22 05:11

Grr4


1 Answers

Unfortunately, Jinja2 is rendered on the server, so it's code doesn't ever run on the client's machine - it can't (easily) get hold of the timezone.
This means that Javascript is run after the Jinja2 template is rendered, so you can't use JS within jinja2 tags.

There are a few ways to get around this/solve your problem:

1) When the user first visits your site (or logs in, if that's possible), have some javascript set a timezone cookie. This can then be read serverside, and passed into the template - something like this:

# On the server
def view_jobs_page(request, response):
    import datetime
    tz = datetime.timedelta(seconds = int(request.cookies["timezone"])) # Pass this into the Jinja2 render function
    # ... Do stuff


# In your template
local time: {{ job.finishtime + tz }}

It's hard to give a more detailed example without knowing the exact stack and code structure that you're using. This also has the downside of using datetime, which you didn't want.

2) Use javascript to apply the timedelta:

<!-- In the head -->
<script>
// When the page loads - the Jinja template is already rendered now
window.onload = function() {
  // Get all the elements with the given class, and map through them
  document.querySelectorAll(".datetime_to_be_adjusted").forEach(function(el){
    var utcTime = moment.utc(el.innerText);  // This is the time in UTC
    utcTime.local();  // Switch to using the browser's local timezone
    el.innerText = utcTime.format('MMMM Do YYYY, h:mm:ss a');  // Write the local time back to the element
  });
}
</script>
...
{% for job in jobs %}
    <a href=”{{ url_for(‘jobs/by_id’,job_id=job.job_id) }}" class="datetime_to_be_adjusted">
        {{ job.finishtime }}
    </a>
{% endfor %}

This of course relies of momentJS being included in the page, and uses it's UTC parsing mechanis.

like image 65
Oliver Fawcett Avatar answered Nov 14 '22 22:11

Oliver Fawcett