Search code examples
djangopython-3.xpython-datetimedjango-timezone

problem with timezone and datetime libs in Django 2 and python 3


I'm a bit confused by the daylight savings handling. I have working on web notifier application in Django 2.0.6 framework and python 3.6. this application provide scheduling notification. for example users schedule message for some hours later or a few days later. this website is available in only one time zone.

I have use this settings in Django:

...

TIME_ZONE = 'Europe/London'
USE_I18N = True
USE_L10N = True
USE_TZ = True

...

when I run this code in python manage.py shell:

>>> from django.utils import timezone
>>> from datetime import datetime
>>> timezone.now()
>>> datetime.now()

django timezone.now() return to me datetime with tzinfo UTC and datetime.now() return to me correct time information with correct time zone info. when I made USE_TZ=False in django setting to find out timezone.now() in django return correct time zone information like datetime.now(). in Django time zone document said: ''This is handy if your users live in more than one time zone and you want to display datetime information according to each user’s wall clock.good practice to store data in UTC in your database. The main reason is Daylight Saving Time (DST). Many countries have a system of DST, where clocks are moved forward in spring and backward in autumn. If you’re working in local time, you’re likely to encounter errors twice a year, when the transitions happen''

Depending on my project type I'm looking for that what is the best practice for time zone config in my Django settings project and solve that problem Django talk about that in time documentation. Please help me

Thanks.


Solution

  • You should enable USE_TZ. If you look carefully, you'll see that datetime.now() does not specify the timezone (naive time), whereas timezone.now() does (timezone-aware time). With USE_TZ=True, all datetime objects are transformed to the absolute UTC time and timezone aware, so that there's no ambiguity about the actual moment in time.

    timezone.now() should give you 14:28 with tzinfo=UTC when in London it's 15:28 (now, in April):

    >>> timezone.now()
    datetime.datetime(2020, 4, 6, 14, 41, 13, 296983, tzinfo=<UTC>)
    >>> datetime.now()
    datetime.datetime(2020, 4, 6, 15, 42, 3, 320929)  # no tzinfo
    

    Imagine your user sets an alarm for October 25th, 2020, 2:30am. Now this is ambiguous, since this time will occur twice in London: Once during DST and an hour later after we've gone back to winter time and moved our clocks from 3am to 2am. But if you change this to UTC, this won't be ambiguous, there's only one 2020/10/25 2:30 UTC (when Europe/London is in winter time when GMT = UTC). So it either has to be 1:30 or 2:30 (UTC).

    So definitely if you're making an app where there's scheduling, use USE_TZ otherwise you'll have issues around DST.