I'm struggling to figure out how timezone works in Django. On my systems I have all datetimes in UTC+00
even with a UTC+02
TIME_ZONE setting.
timezone.get_default_timezone()
<DstTzInfo 'Europe/Rome' RMT+0:50:00 STD>
timezone.get_current_timezone()
<DstTzInfo 'Europe/Rome' RMT+0:50:00 STD>
I'm using PostgreSQL
as backend database and I'm using the following settings:
TIME_ZONE = 'Europe/Rome'
USE_TZ = True
The documentations about PostgreSQL say:
... if you’re using PostgreSQL, you can switch between USE_TZ = False and USE_TZ = True freely. The database connection’s time zone will be set to TIME_ZONE or UTC respectively, so that Django obtains correct datetimes in all cases. You don’t need to perform any data conversions.
If from shell I try to get the date_joined
field of an User, this one is UTC+00 and not converted to UTC+02 (as expected since I'm using TIME_ZONE)
admin.date_joined
datetime.datetime(2017, 7, 12, 15, 22, 58, tzinfo=<UTC>)
str(admin.date_joined)
'2017-07-12 15:22:58+00:00'
The serialized object (DRF) contain the same wrong datetime of course (in UTC+00)
"date_joined": "2017-07-12T15:22:58Z",
Django also offer the possibility to set the favorite TIME_ZONE to end user 's with activate() method, but this is a different thing. By default when I retrieve data from the database all datetimes should be converted to the relative TIME_ZONE settings right?
What I'm missing? where I get wrong?
It's important to understand that datetimes
are converted to the current time zone only when "rendering". That is, when using templates, forms, or, in the case of Django Rest Framework, serializers.
The timezone of the Python datetime
object depends on the database connection, and is usually UTC
. One reason for this is that timezones are primarily a display issue, so it doesn't really matter what the timezone of your Python object is. A more important reason is that timezone conversions are potentially lossy (since many timezones have ambiguous times around DST), so you really don't want to do this sort of conversion until the very last step.