同事在開發(fā)過程中遇到了時區(qū)問題,經(jīng)過同事們的努力問題最終解決了。這讓我發(fā)現(xiàn)時區(qū)接口比我想像的要復(fù)雜一些。
首先,時間如果是一個物理概念,那么它跟空間是無關(guān)的。例如經(jīng)典的 POSIX 時間戳,以 Epoch 為起點記錄時間差。Epoch 是一個物理時間,全球都代表同一個意思,那么這種計時方法就是跟空間無關(guān)的。
然而因為地球是個球形,全球?qū)Α?4 點」這類感受是不一致的。在美國的 14 點代表的物理時間,地球上其他地方可能是晚上,要求這些地方用 14 點表示一個晚上的時間,他們必然不會舒服。這就是劃分時區(qū)的意義。
當(dāng)我說 2009 年 12 月 23 日 12 點的時候,這個表述嚴(yán)格來說不能完全表示一個物理時間。日本的 2009 年 12 月 23 日 12 點和中國的 2009 年 12 月 23 日 12 點是不一樣的物理時間。所以我應(yīng)該說「 2009 年 12 月 23 日 12 點,UTC+8」后面的 UTC+8 表示這個時間比 UTC 時間多 8 個小時,也就是說是中國時間。
「 2009 年 12 月 23 日 12 點,UTC+8」和 「 2009 年 12 月 23 日 4 點,UTC」是同一個時間嗎?從時區(qū)時間來看,是不一樣的;從物理時間來看,是一樣的。
但是如果我們一直生活在同一個時區(qū),這也是我們大多數(shù)人的體驗,表示時間的描述里對時區(qū)的描述就顯得很多余,這時我們習(xí)慣于省略時區(qū)的表述。
Python 的 datetime 文檔 表示,datetime 類別,有兩種實例,一種是「aware」的,一種是「naive」的。即前一種包含了時區(qū)信息,后一種省略了時區(qū)信息。舉例幾個接口:
-
datetime.now(tz=None)獲取當(dāng)?shù)貢r間,當(dāng)
tz是None返回的是 naive 的,否則是 aware 的。 -
datetime.utctime()把當(dāng)?shù)貢r間轉(zhuǎn)換成 UTC 時區(qū)的時間,但是得到的
datetime是 naive 的。 -
datetime.timestamp(self)計算當(dāng)前時間(如果是 naive 的,看作是當(dāng)?shù)貢r間)的 Unix 時間戳。得到一個距離 Epoch 的時間長度的浮點數(shù)描述。
從上面的描述可以看出,datetime.utcnow().timestamp() 得到的是一個奇怪的值,幾乎沒有任何意義。
Python 的文檔也建議,如果要取 UTC 時間,應(yīng)該使用 datetime.now(timezone.utc),這樣就可以得到 aware 的 UTC 時間。它的 timestamp() 方法,就可以得出正確的 Unix 時間戳。