Django’s settings
configuration has a USE_TZ
item with a default value of True. Many people are not quite sure what this configuration item does, except that it has to do with time zones. Let’s talk about it in detail.
First, we need to understand what offset-aware
and offset-navie
are.
offset-aware and offset-navie
In Python, there is a datetime
module that I’m sure you’re familiar with. But few people know that this module’s time can also be divided into the following two types.
- offset-naive: the type without time zone
- offset-aware: the type with time zone
And, these two types of time cannot be compared directly, such as subtraction, addition, time comparison, etc. The following exception will be thrown.
|
|
The fundamental reason is that one has time zone information and the other does not.
We can determine exactly which of the two is the case by looking at the tzinfo
property of the datetime
object.
It is clear that datetime.datetime.now()
is an offset-naive
type time object with no time zone information.
We can convert an offset-naive
type time object to an offset-aware
type time object with the help of the pytz
module.
First install the pytz
module: pytz
module.
|
|
To test.
Conversely, it is possible to convert an offset-aware
type to an offset-naive
type.
USE_TZ configuration
Back to the Django species. We know that when you install Django, you install a pytz
module by default, and then under django.utils
you have a timezone
module, which is actually pytz.timezone
.
First, let’s be clear about one thing. USE_TZ
defaults to True in Django’s settings
configuration, which means that by default, Django databases store date data with timezone information, which is the offset-aware
type.
This causes us some times to do time comparison or add or subtract operations, which will throw the exceptions mentioned earlier.
|
|
So what to do?
The most primitive and simple way, naturally, is to convert the time type, using the method in the example above, and unify it so that it can be compared.
There is also a simpler way, that is to set USE_TZ
to False, at this time, the time object saved in the database does not contain time zone information, and the native datetime.datetime
is a type, both are offset-naive
type, naturally there is no conflict.
Tips: You should set USE_TZ
to False at the beginning of the project, before creating the data table, otherwise the previously saved time data may still have time zone information.
In fact, there is a more applicable method, which is to keep USE_TZ
as True, but instead of using the datetime
library, use timezone
to get the now
time.
In this way, everyone comes with time zone information and is naturally comparable.