Django 对时区处理的核心逻辑是:
即使网站用户只有一个地区,Django 也 建议 用 UTC 存储时间,来避免有些地区使用的夏令时(DST)引起一个时间重复出现多次的问题。
USE_TZ
设置:
TIME_ZONE
定义的的本地时区的 naive 对象(有一些不太重要的例外)TIME_ZONE
设置的意义是一个默认的时区。它的逻辑是:
USE_TZ
为 False
时,Django 会把 DATETIME 对象转换到这个时区再去存储;你在 DB 中的值会是这个时区的时间(即使 DB 本身不存储时区,如 MySQL)USE_TZ
为 True
时,Django 会把 DATETIME 对象转换到 UTC 再去存储;你在 DB 中的值会是 UTC 时间USE_TZ
为 False
时,逻辑上被认为是 TIME_ZONE
设定的时区(但 Django 内部仍然使用 naive object);在展示到 template 时,不会被转换时区USE_TZ
为 True
时,被认为是 UTC 时间,Django 内部会使用 aware object;在展示到 template 时,会被转换为应用代码中指定的用户时区;如果代码没有指定,会被转换为 TIME_ZONE
设置的时区这个逻辑看起来很复杂。但是从演变的角度看就容易理解:
TIME_ZONE
设置早于 USE_TZ
设置。在 Web 还没有蓬勃发展的年代,一个网站往往仅服务一个国家 / 地区的用户。因此一个 TIME_ZONE
设置就足够了USE_TZ
设置。当 USE_TZ
被打开时,TIME_ZONE
的含义 从网站的唯一时区,变成了 当没有给用户指定一个时区时 的默认时区