一般設置
LANGUAGE_CODE = 'zh-hans' #admin的語言為中文
TIME_ZONE = 'Asia/Shanghai' #采用東八區時間
USE_I18N = True
USE_L10N = True
USE_TZ = False #是否采用UTC時間
- 在Django的配置文件
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 啟用 USE_TZ = True 的善后工作
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
后,處理時間方面,有兩條 “黃金法則”:
- 保證存儲到數據庫中的是 UTC 時間;
- 在函數之間傳遞時間參數時,確保時間已經轉換成 UTC 時間;
比如,通常獲取當前時間用的是:
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