Python與Django的時區問題


在編碼中牽扯到時間問題的時候,總是容易被時區問題搞混,一直以來,都是反復試驗應付過去,今天終於搞清楚了個中緣由,一個心結也得以化解。

Python 的時區問題

datetime.today() / datetime.now()

這兩個函數獲得的是當前的系統時間,但得到的datetime對象中的tzinfo是空的,即使系統中設置了時區。

datetime.utcnow()

這個函數獲得當前的utc時間,應該是根據當前系統時間和時區來計算的。

例如系統時間為14:00,時區為 Asia/Shanghai (北京時間),utcnow返回時間為 6:00。同樣,得到的對象中的tzinfo 為空。

環境變量 TZ 對以上函數的影響:

當系統中設置了環境變量 TZ 的時候,或者在python中設置了 os.environ[‘TZ’] 的時候,上面的函數獲取的時間便是TZ對應時區的時間。其實這里可以認為 TZ 影響的不是這些函數,而是影響的系統時間,這可以從date命令的返回結果看出。datetime.now() 與 date命令返回的結果總是一致的。

Django的時區問題

明白了上面幾個python中的函數,django的時區問題看起來就簡單了。

在django的setting中,有一個設置是 TIME_ZONE, 來設置程序中使用的時區。

從django的文檔中得知,TIME_ZONE的作用就是改變 os.environ[‘TZ’]  ,但改變os.environ[‘TZ’]  並不會改變系統環境變量 TZ , 因此,如果 TIME_ZONE 的設置於系統時區設置不一致,則在程序中 datetime.now() 獲得的時間就與 date 命令的時間不一致了。

因此,TIME_ZONE 應該設置為程序希望使用的時區。對於一個本地的程序,TIME_ZONE 設置為與系統時區一樣即可;而對於一個國際化的應用,TIME_ZONE 最好設置為UTC,在顯示的時候再根據當前用戶所在的時區做調整。

手冊

classmethod datetime.now([tz])

Return the current local date and time. If optional argument tz is None or not specified, this is like today(), but, if possible, supplies more precision than can be gotten from going through a time.time() timestamp (for example, this may be possible on platforms supplying the C gettimeofday() function).

Else tz must be an instance of a class tzinfo subclass, and the current date and time are converted to tz‘s time zone. In this case the result is equivalent to tz.fromutc(datetime.utcnow().replace(tzinfo=tz)). See also today(), utcnow().

classmethod datetime.utcnow()

Return the current UTC date and time, with tzinfo None. This is like now(), but returns the current UTC date and time, as a naivedatetime object. See also now().

時區轉換代碼

1
2
3
4
import pytz
....
#dt the datetime var
dt.replace(tzinfo = pytz.utc).astimezone(pytz.timezone( 'Asia/Shanghai' ))


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM