一般设置
LANGUAGE_CODE = 'zh-hans' #admin的语言为中文
TIME_ZONE = 'Asia/Shanghai' #采用东八区时间
USE_I18N = True
USE_L10N = True
USE_TZ = False #是否采用UTC时间
settings.py
中,有两个配置参数是跟时间与时区有关的,分别是TIME_ZONE
和USE_TZ
USE_TZ
设置为True
时,Django会使用系统默认设置的时区,即America/Chicago
,此时的TIME_ZONE
不管有没有设置都不起作用。
USE_TZ
设置为False
,而TIME_ZONE
设置为None
,则Django还是会使用默认的America/Chicago
时间。若TIME_ZONE
设置为其它时区的话,则还要分情况,如果是Windows系统,则TIME_ZONE
设置是没用的,Django会使用本机的时间。如果为其他系统,则使用该时区的时间,入设置USE_TZ = False
, TIME_ZONE = 'Asia/Shanghai'
, 则使用上海的UTC
时间Django 1.4 之后,时区的问题总算解决了。虽然 pytz 库 是可选的,但 pytz 可以帮助 Django 识别 TIME_ZONE = 'Asia/Shanghai'
对应的时区是 UTC+8 时间,因此建议启用 USE_TZ = True
的同时也安装 pytz。
1.4 之前,Django 对时区毫无概念,对时间的存取、展示不做任何处理,数据库里存储的通常是本地时间(local time)。1.4 之后,在 settings
里面设置 USE_TZ = True
即让 Django 内部把时间全部当成 UTC 时间(北京时间为 UTC+8 )对待。
但这么做还没完,还有一些琐碎的善后工作要做 — 数据和老代码的迁移,不然时间的存取、展示都会有差错。
如果之前设置了 TIME_ZONE = 'Asia/Shanghai'
,那么实际存储在数据库中的是 UTC+8 的时间。启用USE_TZ = True
我们要把数据库中所有的时间戳(timestamp)字段全部转换成 UTC 时间。
转换到 UTC 时间有两个方法(注:PostgreSQL 有专门的方法):
manage.py shell
进入 Django shell 环境,用 Model.objects.all()
循环遍历包含DateTimeField
字段的模型,减去 timedelta(hours=8)
;UPDATE
语句;第一个方法不推荐使用,因为 ORM 的 save()
方法会触发 post_save
signal,可能会产生不希望看到的副作用。
第二个方法是安全的(注意备份数据库),MySQL 下可以用如下 SQL 语句更新时间戳:
UPDATE `your_model` SET `last_modified` = DATE_SUB(`last_modified`, INTERVAL 8 HOUR) WHERE 1;
PostgreSQL 的时间字段原生支持时区,所以处理方法不太一样,详见 Django 官方文档 Time zones。
启用 USE_TZ = True
后,处理时间方面,有两条 “黄金法则”:
比如,通常获取当前时间用的是:
import datetime now = datetime.datetime.now()
启用 USE_TZ = True
后,需要写成:
import datetime from django.utils.timezone import utc now = datetime.datetime.utcnow().replace(tzinfo=utc)
保证 now
变量存放的是 UTC 时间。
再如 fromtimestamp()
这个函数,启用 USE_TZ = True
后应使用 utcfromtimestamp()
函数替代。
除非应用支持用户设置自己所在的时区,通常我们不需要关心模板的时区问题。模板在展示时间的时候,会使用 settings.TIME_ZONE
中的设置自动把 UTC 时间转成 settings.TIME_ZONE
所在时区的时间渲染。
如果确实需要支持用户设置时区,参考 Django 官方文档 Time zones。
附录
Django 官方网站对 timezone 的说明:
https://docs.djangoproject.com/en/1.11/topics/i18n/timezones/
参考链接:
https://blog.csdn.net/wy00703/article/details/45071277
https://blog.csdn.net/qq_37049781/article/details/79347278
https://www.cnblogs.com/brad1994/p/6761110.html
本文链接:http://task.lmcjl.com/news/15996.html