I have aware datetime instances (where tzinfo = "America/Los_Angeles"
) that I would like to save to a model.
Should I convert it to UTC somehow before saving? Or can I just save it as is, since it's aware of its own timezone? Do I need to convert it to users' timezones later with activate()
, or will Django do that for me, since the instance is aware?
I'm most curious what the conventions are in regards to this. Thanks in advance.
If it is timezone aware and you have USE_TZ
set to True
in your settings.py
django will automatically convert it to UTC when you save it.
When you retrieve it from the DB later it will be timezone aware but set to UTC: django will not save the timezone it used to be.
When you display the datetime in a template it will be converted to the timezone set by TIME_ZONE
in your settings.py
, unless you utilize django's timezone utilities to activate a different timezone.
You do not have to convert it to UTC before saving it as Django will automatically do that for you. When you retrieve it, it will be retrieved as the timezone that was defined in the TIMEZONE
setting.
You can override that with activate()
and to see the current timezone, use django.utils.timezone.get_current_timezone()
.
This means that the time you retrieve from the database may be different than the timezone of the datetime object you used to save the object originally. However, it will still be the same moment in time.
If you have a timezone for each user, you should save this with the user's profile and call activate()
with the user's timezone BEFORE retrieving the model instance that contains the DateTimeField
. The retrieved object will be in the appropriate timezone.
Alternatively you can use the override()
context manager.
If you are sure you always want the datetime
objects in the user's timezone instead of the server's timezone, write a custom middleware to call activate()
on request.user
. You will need to store/retrieve the timezone yourself as Django has no way of knowing what the user's timezone is and does not store it in the User model by default.