[Python] datetime 轉換 timestamp — 時區問題

PC Chen
程式乾貨
Published in
Apr 11, 2021

工作上因為會在不同的機器上開發,兩邊機器的時區又剛好一個+0、一個+8,常常因為這個坑導致轉換過程有誤,因此決定來記錄一下解決方式。

前言 — 情境

在時區+0 的遠端機器上輸入 datetime(2021, 4, 6) ,會自動把這個輸入的 datetime 判斷成是 +0 的時區、而不是自己本地機器所在的 +8。但是在程式開發時,腦袋通常不會這麼即時地做時區轉換,加上開發環境可能是在本地、但是部署到遠端時就發現忘了轉換到+0,如此轉換成 timestamp 的時候就又錯了,資料整個撈錯QQ。

科普一下

所謂的 時間戳timestamp,是計算「(GMT+0) 1970–01–01 00:00:00」到現在時間(+0)所經過的秒數,因此相對地也代表了 +0 時區的時間,在將 datetime 轉換成 timestamp 時要特別注意自己所在的時區。例如現在我的本地電腦是在 +8 時區:
$ date +%z -> 查看機器目前的時區

輸入指令 date +%z 可查看所在時區

這時我把 datetime(2021, 4, 6) 轉換成 timestamp:

轉換的結果如下:

1617638400.0 #轉換結果

這時我把環境轉到 +0 機器上,一樣先來查個時區:

ip碼一下~

接著一樣代碼把 datetime(2021, 4, 6) 轉換成 timestamp:

轉換結果會發現值變大了:

1617667200.0 (<剛剛的1617638400.0)

所以,到底哪個才是對的呢?

先說結論,第一步在+8的值(1617638400.0)才是我們要的!可是為什麼跑到+0的機器上轉換時,值就會變大了呢?

答案其實很簡單,還記得一開始我們說 timestamp 其實是相對於 +0 的時間算經過多久的秒數。所以當我們在+8的機器上,把 datetime(2021,4,6) 轉換成 timestamp 時,會把這個時間先轉成 +0: 2021-04-05 16:00:00、再將+0的時間轉成timestamp。

相對地,如果在+0的機器上,把輸入的 datetime(2021,4,6) 轉換成 timestamp 時,這個時候 python 會判斷這個時間已經是 +0 的時間,所以就直接轉換成timestamp。
再更白話一點,在+0輸入的 dateimte(2021,4,6) ,如果把它翻譯成+8其實是: 2021-04-06 08:00:00,也就是其實我們想要轉換的 datetime 其實是比較大的,這也就是為什麼轉換出來的 timestamp 會比較大。

解法

這樣子每次都要根據不同機器、去手動調整我輸入的時間到底+0 or +8 似乎有點麻煩,還好 datetime 本身有 timezone 讓我們可以直接指定輸入的時間所在的時區,代碼如下:

運行在本地機器+8:

+8環境執行代碼

運行在遠端機器+0:

+0環境執行代碼

可以看到,轉換的結果都一樣是 1617638400.0 了(撒花~

--

--

PC Chen
程式乾貨

喜歡接觸與動手實作各種軟體技術的後端數據工程師 A data- backend engineer who is enthusiastic in learning and implementing any techniques in software engineering.