5

I am using Django 1.11. My settings.py has following configured:

TIME_ZONE = 'Asia/Calcutta'
USE_I18N = True
USE_L10N = True
USE_TZ = True

which is IST (Indian Standard Time). My system is set to IST. MySQL current_time returns IST, Django's server when running, shows timestamp in IST. Python's datetime.now() also gives IST.

Now the problem is, my models.py has following fields:

created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

and the database is MySQL. When I insert any record in it, the timestamps are in UTC. I was thinking of adding some middleware, as suggested by this answer, but that doesn't feel to be the recommended way. Why is it taking UTC even when everywhere IST has been configured? Am I missing some config that needs to be set separately for models?

Please note that this question is not similar to what I require. I want to change the overall timezone, so that it is effective in model's too.

Kevin Christopher Henry
  • 46,175
  • 7
  • 116
  • 102
Rakmo
  • 1,926
  • 3
  • 19
  • 37
  • try USE_TZ = True – Vaibhav Mar 22 '18 at 09:47
  • 1
    check this https://www.percona.com/blog/2015/01/07/django-with-time-zone-support-and-mysql/ – Vaibhav Mar 22 '18 at 10:00
  • I've already set `USE_TZ = True`. This https://www.percona.com/blog/2015/01/07/django-with-time-zone-support-and-mysql/ does work, but it is again sort of a middleware. I am interested in knowing that from where is Model still taking UTC, when I've set IST everywhere, and I want to update that exact point, instead of using any middleware each time. – Rakmo Mar 22 '18 at 10:22
  • @KevinChristopherHenry Thanks, that's what I was looking for. So, if I change it to `False`, will it work fine? After changing it to `False` , will it take System's timezone or the timezone specified in settings ? – Rakmo Mar 22 '18 at 16:59

1 Answers1

14

datetimes will always be stored in UTC if USE_TZ is True.

The only way around that is to set USE_TZ to False. auto_now uses django.utils.timezone.now(), which is defined to do the following:

If USE_TZ is False, this will be a naive datetime (i.e. a datetime without an associated timezone) that represents the current time in the system’s local timezone.

Which sounds like what you're asking for.

But are you sure that's what you want? Since Asia/Calcutta had DST in the past there will be times that you simply can't represent unambiguously in the database. That's why UTC is the standard choice for storing datetimes.

Kevin Christopher Henry
  • 46,175
  • 7
  • 116
  • 102