【轉】Golang中 time.Parse和time.Format的時區問題


原文:https://www.zhetenga.com/view/Golang%E4%B8%AD%20time.Parse%E5%92%8Ctime.Format%E7%9A%84%E6%97%B6%E5%8C%BA%E9%97%AE%E9%A2%98-674f19176.html

------------------------------------------

涉及到時間處理時,Parse 和 Format 是最為常見的處理了。

Parse:將字符串格式的時間轉為 time.Time,類似 PHP 中的 strtotime;Format:將 time.Time 格式化為字符串格式的時間,類似 PHP 中的 timetostr。

提到時間,它一定需要跟時區一起才有意義,比如 15:30:00 這個時間,其實並不明確,因為你不知道這是北京時間還是東京時間。而一般人的理解里,如果沒提到時區,就默認是當地的時區,比如我說 15:30:00,大家都能理解為下午三點,是因為同在北京時區里。

回到 time.Format,它返回的是固定的字符串,格式化時它是需要明確時區信息的,但 Format 函數卻沒有時區參數。事實上它的時區信息來源於 time.Time 結構體的 loc 字段,而並不允許作為參數傳入。這也解釋了為什么 time.Now().Format() 會返回當地時區的時間字符串,因為 time.Now() 返回的 time.Time 默認是當地時區。

type Time struct {

sec int64

nsec int32

loc *Location

}

總結起來就是:time.Format 的時區信息來源於 Time 結構體中的 loc,time.Now().Format() 返回的是當地時區的時間。

然后是 time.Parse,如果它的參數沒有帶入時區信息,比如沒有 +0800 這樣的信息,它將默認使用 UTC 時間,這意味着:

s := time.Now().Format("2006-01-02 15:04:05")

t, _ := time.Parse("2006-01-02 15:04:05", s)

上面的 s 和 t 已經完全不一樣了,因為 s 返回的是當地時區,而 t 則變成了 UTC 時間。這也解釋了為什么經過這么一個習慣性操作,得到的時間居然是不符合預期的了。

正確的做法是使用 ParseInLocation 來 Parse 明確是同一時間的不帶時間信息的時間字符串:

s := time.Now().Format("2006-01-02 15:04:05")

t, _ := time.ParseInLocation("2006-01-02 15:04:05", s, time.Local)

這樣做才會符合習慣於 strtotime 和 timetostr 的結果預期。

總結起來就是:如果時間字符串中帶了時區信息才去使用 time.Parse,否則使用 time.ParseInLocation。


免責聲明!

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



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