Django and timezones ... how to initialize a field to now() in the in clients time zone?

146 views
Skip to first unread message

Bernd Wechner

unread,
Jan 21, 2017, 4:40:15 AM1/21/17
to Django users
I have a model with this field:

date_time = models.DateTimeField(default=timezone.now)

if I look at the generic create form, it inializes the date_time field with now in UTC, not in local time.

Now I appreciate there are two things at play here:
  1. the desired UX is to see now in my time zone.
  2. Django, running on the server has no idea what my time zone is.
Now I can think my way through this and find some solutions, not short of imagination here. But as I work on nutting one out, I am struck, as ever, with the notion that 1. is surely a ubiquitous use case ... namely I cannot seriously be the first person to have this desire or tackle this problem and is there not a stock standard approach in Django to doing this?

As I read it I can find the time zone in Javascript at the client side:

This works fine for example:

    var tz_name = jstz.determine().name();
   
var tz_offset = new Date().getTimezoneOffset()/60;

giving me pleasing results (though I appreciate, before anyone points it out, that pleasing results are by no means guaranteed as it as it is premised on the correct TZ configuration of the client computer among other things, but the application in mind does not REQUIRE time accuracy (am just logging events that happened at a given time and timezone errors are of no practical data integrity or security concerns for a few good reasons) .

And I can submit these in hidden fields too.

But the obvious solution, which I find a tad kludgy alas is at the client side in JS to find the date_time input field, and adjust it's value from UTC to local time. Right now it's presenting as UTC.

Even if I could find a way to ask Django to use a different timezone (tmiezone.activate) it won't kow what Timezone until it's heard from the client. And it's not in HTTP headers alas, though someone thinks it should be:

On submission of course as I can submit the TZ info in hidden fields it should be easy to convert the submission back to UTC for saving into the database.

Still, I wonder openly, is this not long solved, more elegantly?

Regards,

Bernd.

Andreas Kuhne

unread,
Jan 22, 2017, 3:12:36 PM1/22/17
to django...@googlegroups.com
Hi,

The problem here is as you say, your server doesn't know the clients timezone. This isn't trivial to find out either. I can help you with some pointers though:
1. ALWAYS save all times in the database in UTC. ALWAYS - never diviate from this - one exception - if you are running a server that will only be used in a specific timezone. Set the default timezone in django to UTC. 
2. You can set the timezone for the current request - https://docs.djangoproject.com/en/1.10/topics/i18n/timezones/#selecting-the-current-time-zone. The problem that you have is to identifiy the users timezone - this isn't that easy - it can be done via a javascript library like the one you are using, or via a project like this: https://github.com/Miserlou/django-easy-timezones.

Regards,

Andréas


--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/4738d161-186d-4205-a148-1f17e5d231ef%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Tom Evans

unread,
Jan 23, 2017, 10:49:27 AM1/23/17
to django...@googlegroups.com
I think you're worrying about the wrong thing here. "Now" is always
the same moment everywhere, it does not matter what timezone is
currently active when it is recorded, only what timezone is active
when it is displayed. As long as you have USE_TZ=True, all your
datetimes will be stored in the database in UTC.

So, the important thing is setting the appropriate current timezone.
As you've discovered, you can perhaps discern the timezone using
javascript. We have a snippet of javascript that determines TZ and
populates a hidden field in the login form with the browser determined
TZ.

At login, this extra parameter is pulled out if available, and
compared to the setting on the users profile. If the users profile has
no current TZ setting, we update their profile with the determined
settings. If the user has manually specified a timezone, we don't
update it or overwrite it.

Finally, we have a small piece of middleware that changes the active
timezone to that indicated on the user's profile, orto the server time
zone if nothing is indicated or the user is not logged in.

Sadly, this isn't code I can share, but we are talking around 40 LOC total.

Cheers

Tom

Bernd Wechner

unread,
Jan 24, 2017, 8:54:43 PM1/24/17
to Django users
Thanks enormously Andreas! Very helpful. Will peruse at leisure later, but in summary:

1) yes saving in UTC always. 
2) hoping to present times on user forms in their local time zone (translate on way to client and again on way back to server so to speak).

Knew it can't have been a first time this need arose and am pleased to see the django-easy-timezones project!

Regards,

Bernd.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages