[Solved]-Django: time zone issue

12👍

Relying on date/time ‘automagic’ is dangerous and these auto_add model parameters are a trap. Always understand the timezone(s) you are dealing with. Python makes this easier by attaching a tzinfo member to its datetime objects. While these objects are ‘naive’ by default, I encourage you to always attach tzinfo detail. Still Python needs some extra help with either python-dateutil or pytz (what I use). Here’s a universal rule though – always store your datetimes in a database as UTC.

Why? Your users may be in different locals, mobile phones and laptops travel, servers are misconfigured or mirrored in different timezones. So many headaches. Datetimes should never be naive and if they are (as in a database) and you need the context, also include a timezone field in the table.

So in your case.

  1. Don’t use the auto_now fields, use a custom save() instead.
  2. Store UTC in the database
  3. If you need to know the timezone – for say a user event – store the timezone in the database as well.
  4. Convert to the necessary/requested timezone

If you are using pytz, the localize() method is great. Python’s datetime object has the useful replace() and astimezone().

One more note, if your database is timezone naive (like MySQL) make sure your datetimes are in UTC and then use replace(tzinfo=None) because the database connector can’t handle tz-aware objects.

Here is a thread with detail on Django’s auto_now fields.

4👍

The simplest/fastest fix [said above by Ajay Yadav] is this ,

Just add TIME_ZONE attribute to the Database’s section in settings.py,

settings.py

# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
        'TIME_ZONE': 'Asia/Tokyo',
    }
}

For the available Timezone choices , See the Official documentation linked below ,

DJANGO TIMEZONE CHOICES

3👍

First off, I would want to store my data as UTC cause its a good starting point.

So let me ask this, Why do you need the time in EST, is this for the end-user, or do you need to do logic on the server and need it in EST?

If its for the enduser, an easy fix is to let the users browser handle converting to the correct time. On the server convert the datetime object to a timestamp:

timestamp = time.mktime(datetime_obj.timetuple()) * 1000

And then on the web page instantiate a Date object:

var date_obj = new Date({{ timestamp }});
var datetime_string = date_obj.toString();
// the datetime_string will be in the users local timezone

Now, on the other hand, if you want to have the time in the correct zone on the server so you can perform logic on it. I recommend using the help of python-dateutil. It will allow you to easily swap to a different timezone:

from datetime import datetime
from dateutil import zoneinfo

from_zone = zoneinfo.gettz('UTC')
to_zone = zoneinfo.gettz('America/New_York')

utc = created # your datetime object from the db


# Tell the datetime object that it's in UTC time zone since 
# datetime objects are 'naive' by default
utc = utc.replace(tzinfo=from_zone)

# Convert time zone
eastern_time = utc.aztimezone(to_zone)

Now if you really wanna store the datetime in EST, you need change the time on the DB server (like Ajay Yadav and gorus said). I don’t know why you want to store them as EST, but then again I don’t know what your application is.

1👍

When you say auto_now_add=True, the value will be added by your database server and not your django server. So you need to set time zone on your database server.

-1👍

Since you edited the question, I’ll edit my answer 🙂 Django cannot control the time zone of your db, so the way to fix this is to update the time zone for your db. For MySql, run this query:

SELECT @@global.time_zone, @@session.time_zone;

This should return SYSTEM, SYSTEM by default, which in your case means “Europe/London”, and the cause of your problem. Now that you’ve verified this, follow the instructions in the first comment on this page:

http://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html

Remember to restart MySql server after you’ve updated the time zone for the changes to take effect.

Leave a comment