同事在開發(fā)過程中遇到了時(shí)區(qū)問題,經(jīng)過同事們的努力問題最終解決了口注。這讓我發(fā)現(xiàn)時(shí)區(qū)接口比我想像的要復(fù)雜一些。
首先君珠,時(shí)間如果是一個(gè)物理概念寝志,那么它跟空間是無關(guān)的。例如經(jīng)典的 POSIX 時(shí)間戳葛躏,以 Epoch 為起點(diǎn)記錄時(shí)間差澈段。Epoch 是一個(gè)物理時(shí)間,全球都代表同一個(gè)意思舰攒,那么這種計(jì)時(shí)方法就是跟空間無關(guān)的败富。
然而因?yàn)榈厍蚴莻€(gè)球形,全球?qū)Α?4 點(diǎn)」這類感受是不一致的摩窃。在美國(guó)的 14 點(diǎn)代表的物理時(shí)間兽叮,地球上其他地方可能是晚上,要求這些地方用 14 點(diǎn)表示一個(gè)晚上的時(shí)間猾愿,他們必然不會(huì)舒服鹦聪。這就是劃分時(shí)區(qū)的意義。
當(dāng)我說 2009 年 12 月 23 日 12 點(diǎn)的時(shí)候蒂秘,這個(gè)表述嚴(yán)格來說不能完全表示一個(gè)物理時(shí)間泽本。日本的 2009 年 12 月 23 日 12 點(diǎn)和中國(guó)的 2009 年 12 月 23 日 12 點(diǎn)是不一樣的物理時(shí)間。所以我應(yīng)該說「 2009 年 12 月 23 日 12 點(diǎn)姻僧,UTC+8」后面的 UTC+8 表示這個(gè)時(shí)間比 UTC 時(shí)間多 8 個(gè)小時(shí)规丽,也就是說是中國(guó)時(shí)間蒲牧。
「 2009 年 12 月 23 日 12 點(diǎn),UTC+8」和 「 2009 年 12 月 23 日 4 點(diǎn)赌莺,UTC」是同一個(gè)時(shí)間嗎冰抢?從時(shí)區(qū)時(shí)間來看考榨,是不一樣的贞铣;從物理時(shí)間來看蜈块,是一樣的摩骨。
但是如果我們一直生活在同一個(gè)時(shí)區(qū)戚丸,這也是我們大多數(shù)人的體驗(yàn)疗疟,表示時(shí)間的描述里對(duì)時(shí)區(qū)的描述就顯得很多余梦抢,這時(shí)我們習(xí)慣于省略時(shí)區(qū)的表述额嘿。
Python 的 datetime 文檔 表示港谊,datetime 類別骇吭,有兩種實(shí)例,一種是「aware」的歧寺,一種是「naive」的燥狰。即前一種包含了時(shí)區(qū)信息,后一種省略了時(shí)區(qū)信息斜筐。舉例幾個(gè)接口:
-
datetime.now(tz=None)
獲取當(dāng)?shù)貢r(shí)間龙致,當(dāng)
tz
是None
返回的是 naive 的,否則是 aware 的顷链。 -
datetime.utctime()
把當(dāng)?shù)貢r(shí)間轉(zhuǎn)換成 UTC 時(shí)區(qū)的時(shí)間目代,但是得到的
datetime
是 naive 的。 -
datetime.timestamp(self)
計(jì)算當(dāng)前時(shí)間(如果是 naive 的嗤练,看作是當(dāng)?shù)貢r(shí)間)的 Unix 時(shí)間戳榛了。得到一個(gè)距離 Epoch 的時(shí)間長(zhǎng)度的浮點(diǎn)數(shù)描述。
從上面的描述可以看出煞抬,datetime.utcnow().timestamp()
得到的是一個(gè)奇怪的值霜大,幾乎沒有任何意義。
Python 的文檔也建議革答,如果要取 UTC 時(shí)間战坤,應(yīng)該使用 datetime.now(timezone.utc)
,這樣就可以得到 aware 的 UTC 時(shí)間残拐。它的 timestamp()
方法途茫,就可以得出正確的 Unix 時(shí)間戳。