Feeling some serious timezone pain

64 views
Skip to first unread message

christophw

unread,
Aug 20, 2014, 8:22:56 AM8/20/14
to django...@googlegroups.com
Hi there,

I'm feeling some pain while wrangling with timezones in an office room booking application.  I'm storing bookings in a MySQL database and want to display them in the timezone local to the office room, so it is not necessarily local to the user's local machine timezone.  

Here is my model's datetime definition:
class Booking(models.Model):
 date_time
= models.DateTimeField()

When the booking is stored, it comes back from a post and I store it in the DB as such:

dt = datetime.datetime.strptime(request.POST["date"] + " " + request.POST["time"], "%Y-%m-%d %H:%M")
dt
= pytz.timezone("America/Toronto").localize(dt)

Printing the value of dt after that call, it looks correct.

Later on, I pull that booking out of my database by ID and render it in my template, rendering the datetime like this:

<small>{{booking.date_time}}</small>

I've tried re-interpreting the timezone after pulling it out of the database, to no avail. When I print the datetime object directly after it is pulled out of MySQL, I get it in UTC like so:
2014-08-30 16:00:00+00:00

Re-interpreting it to force it into the office's local timezone, I get the correct result but 1 hour off is still rendered in the web browser
# returns 2014-08-30 12:00:00-04:00
booking
.date_time = pytz.timezone("America/Toronto").normalize(booking.date_time)



The result of this is the time is rendered 1 hour behind the actual time.  This is consistent across all datetimes I've tried, and I seem to be unable to get Django to render the correct time.

My question is this: Why is my datetime consistently rendering 1 hour off, and how do I wrangle it into rendering at the true time?

Geoffrey S. Knauth

unread,
Aug 20, 2014, 8:36:58 AM8/20/14
to django...@googlegroups.com
2014-08-30 16:00:00+00:00 GMT
2014-08-30 12:00:00-04:00 Toronto (Summer)

This looks correct to me.  Maybe you were expecting the timezone to be -05:00?  That would be standard time (winter).  Daylight savings time is -04:00.
--
Geoffrey S. Knauth | http://knauth.org/gsk
 
On Wed, Aug 20, 2014, at 08:22, christophw wrote:
Hi there,
 
I'm feeling some pain while wrangling with timezones in an office room booking application.  I'm storing bookings in a MySQL database and want to display them in the timezone local to the office room, so it is not necessarily local to the user's local machine timezone.  
 
Here is my model's datetime definition:
classBooking(models.Model):
 date_time = models.DateTimeField()
 
When the booking is stored, it comes back from a post and I store it in the DB as such:
 
dt = datetime.datetime.strptime(request.POST["date"]+" "+ request.POST["time"],"%Y-%m-%d %H:%M")
dt = pytz.timezone("America/Toronto").localize(dt)
 
Printing the value of dt after that call, it looks correct.
 
Later on, I pull that booking out of my database by ID and render it in my template, rendering the datetime like this:
 
<small>{{booking.date_time}}</small>

 
I've tried re-interpreting the timezone after pulling it out of the database, to no avail. When I print the datetime object directly after it is pulled out of MySQL, I get it in UTC like so:
2014-08-3016:00:00+00:00

 
Re-interpreting it to force it into the office's local timezone, I get the correct result but 1 hour off is still rendered in the web browser
 
# returns 2014-08-30 12:00:00-04:00
booking.date_time = pytz.timezone("America/Toronto").normalize(booking.date_time)
 
 
 
The result of this is the time is rendered 1 hour behind the actual time.  This is consistent across all datetimes I've tried, and I seem to be unable to get Django to render the correct time.
 
My question is this: Why is my datetime consistently rendering 1 hour off, and how do I wrangle it into rendering at the true time?


--
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...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
 
 
 
 
 

Robin

unread,
Aug 20, 2014, 8:51:40 AM8/20/14
to django...@googlegroups.com
Guys
The UK is currently on British Summer Time (BST) so

2014-08-30 16:00:00 BST
2014-08-30 11:00:00 Toronto (Summer)

Greenwich Mean Time (GMT) as a term is not used as frequently as previously. The preferred term is Universal Coordinated Time (UTC), as some overseas users confusingly equate GMT with the current time in Britain, after any adjustment for summer time.


Robin St.Clair

Chris Whiten

unread,
Aug 20, 2014, 9:07:50 AM8/20/14
to django...@googlegroups.com
That's exactly right, but what's rendered in the browser is 11 AM rather than 12:00

Erik Cederstrand

unread,
Aug 20, 2014, 9:09:24 AM8/20/14
to Django Users

Den 20/08/2014 kl. 14.22 skrev christophw <chris....@gmail.com>:

> When the booking is stored, it comes back from a post and I store it in the DB as such:
>
> dt = datetime.datetime.strptime(request.POST["date"] + " " + request.POST["time"], "%Y-%m-%d %H:%M")
> dt = pytz.timezone("America/Toronto").localize(dt)

In my book, it's bad practice to store anything other than UTC in the database. Time localization should be done in the UI layer according to the location or preferences of the user.

Also, beware that local datetimes cannot uniquely identify a datetime during the shift from DST to normal time.

Erik

Chris Whiten

unread,
Aug 20, 2014, 6:09:19 PM8/20/14
to django...@googlegroups.com
I can understand that sentiment... But that doesn't change the fact that 12:00 PM on the Python side renders as 11 AM in the template, right?

Erik Cederstrand

unread,
Aug 21, 2014, 7:47:08 AM8/21/14
to Django Users
Den 21/08/2014 kl. 00.09 skrev Chris Whiten <chris....@gmail.com>:

> I can understand that sentiment... But that doesn't change the fact that 12:00 PM on the Python side renders as 11 AM in the template, right?

Your database stores the datetime as (the equivalent of) 16:00 UTC, right? Which is expected, because you POST'ed 12:00 Toronto time, and the date was in August, and Toronto is presumably 4 hours behind of UTC in August (haven't checked). But your tamplate renders the correct datetime wrong?So the template must be doing the wrong thing.

Can you show your settings.py timezone values? And the template code which renders the localized datetime? (see https://docs.djangoproject.com/en/dev/topics/i18n/timezones/#time-zone-aware-output-in-templates)

Erik

Geoffrey S. Knauth

unread,
Aug 21, 2014, 9:04:33 AM8/21/14
to django...@googlegroups.com
Could there be something in or running the template that has a DST
(daylight savings time) value turned off?
--
Geoffrey S. Knauth | http://knauth.org/gsk

Tom Evans

unread,
Aug 21, 2014, 9:56:29 AM8/21/14
to django...@googlegroups.com
On Wed, Aug 20, 2014 at 1:22 PM, christophw <chris....@gmail.com> wrote:
> Hi there,
>
> I'm feeling some pain while wrangling with timezones in an office room
> booking application. I'm storing bookings in a MySQL database and want to
> display them in the timezone local to the office room, so it is not
> necessarily local to the user's local machine timezone.
>
> Here is my model's datetime definition:
> class Booking(models.Model):
> date_time = models.DateTimeField()
>
> When the booking is stored, it comes back from a post and I store it in the
> DB as such:
>
> dt = datetime.datetime.strptime(request.POST["date"] + " " +
> request.POST["time"], "%Y-%m-%d %H:%M")
> dt = pytz.timezone("America/Toronto").localize(dt)
>
> Printing the value of dt after that call, it looks correct.

Take your localized datetime that you think looks correct, and convert
it to UTC. Is it right? Is your localization taking in to account DST
correctly? "America/Toronto" is either Eastern Standard Time or
Eastern Daylight Time according to my brief research, and presumably
right now it is the latter.

Trying from scratch. The current time in Toronto is 9:38, this should
correspond to 1:38 when converted back to UTC

>>> from datetime import datetime
>>> import pytz
>>> dt = datetime.strptime('2014-8-21 9:38', "%Y-%m-%d %H:%M")
>>> dt2 = pytz.timezone("America/Toronto").localize(dt)
>>> dt2
datetime.datetime(2014, 8, 21, 9, 38, tzinfo=<DstTzInfo
'America/Toronto' EDT-1 day, 20:00:00 DST>)
>>> dt2.astimezone(pytz.utc)
datetime.datetime(2014, 8, 21, 13, 38, tzinfo=<UTC>)

I'm convinced this is a DST handling issue. If it is not when it goes
*in* to the database, perhaps it is when it comes *out*.
What do you have for settings.TIME_ZONE and settings.USE_TZ?
If you examine the localized dt that is pulled from the DB, what
tzinfo is set on it?

Cheers

Tom

Subodh Nijsure

unread,
Aug 21, 2014, 4:14:23 PM8/21/14
to django...@googlegroups.com
You could consider passing the timestamp in UTC to the template and
then convert it to browser's timezone using javascript function -
convertUTCDateToLocalDate(data)?

-Subodh
Reply all
Reply to author
Forward
0 new messages