簡體   English   中英

為什么time.Parse沒有使用時區?

[英]Why is time.Parse not using the timezone?

為什么time.Parse不使用時區信息? 它應該為不同的時區返回不同的時間。

package main

import (
    "fmt"
    "time"
)

func main() {
    t, err := time.Parse("2006-01-02 MST", "2018-05-11 IST")
    if err != nil {
        return
    }
    t2, err := time.Parse("2006-01-02 MST", "2018-05-11 UTC")
    if err != nil {
        return
    }
    fmt.Println(t.Unix())
    fmt.Println(t2.Unix())
}

輸出:

1525996800
1525996800

對問題本身的一些解釋:

這兩個時間戳2018-05-11 IST2018-05-11 UTC不指定相同的時間瞬間,因為IST具有與UTC不同的偏移:印度標准時間(IST)比協調世界時(UTC)早5:30 )。

並且Time.Unix()返回自參考時間(1970年1月1日UTC)以來經過的經過的秒數。 這意味着輸出應該是不同的!

在PlayGround上運行代碼確實會產生錯誤的結果( 鏈接 )。

這是一個與時區相關的問題。 如果您嘗試加載IST時區:

loc, err := time.LoadLocation("IST")
fmt.Println(loc, err)

輸出:

UTC cannot find IST in zip file /usr/local/go/lib/time/zoneinfo.zip

並且不支持“IST”的原因是因為它含糊不清。 它可能意味着印度,愛爾蘭,以色列等時區,它們具有不同的區域偏移和規則。

time.Parse()文檔說明了這一點

如果區域縮寫未知,則Parse將時間記錄為具有給定區域縮寫和零偏移的制造位置。

因此, parse.Parse()返回的time.time將像UTC區域一樣具有0偏移量,因此它將導致相同的“unix time”( Time.Unix()將返回相同的值)。

但是在本地(使用我的CET)時區運行它會得到不同的正確結果:

t, err := time.Parse("2006-01-02 MST", "2018-05-11 CET")
if err != nil {
    panic(err)
}
t2, err := time.Parse("2006-01-02 MST", "2018-05-11 UTC")
if err != nil {
    panic(err)
}
fmt.Println(t)
fmt.Println(t2)

fmt.Println(t.Unix())
fmt.Println(t2.Unix())

輸出:

2018-05-11 01:00:00 +0200 CEST
2018-05-11 00:00:00 +0000 UTC
1525993200
1525996800

time.Parse()文檔說明了使用區域縮寫解析時間:

在使用區域縮寫(如MST)解析時間時,如果區域縮寫在當前位置具有已定義的偏移量,則使用該偏移量。 無論位置如何,區域縮寫“UTC”都被識別為UTC。 如果區域縮寫未知,則Parse將時間記錄為具有給定區域縮寫和零偏移的制造位置。 這種選擇意味着可以無損地使用相同的布局解析和重新格式化這樣的時間,但是表示中使用的確切時刻將因實際的區域偏移而不同。 要避免此類問題,請首選使用數字區域偏移的時間布局,或使用ParseInLocation。

文檔建議使用帶有數字區域偏移的布局進行解析,如下所示:

t, err := time.Parse("2006-01-02 -0700", "2018-05-11 +0530")
if err != nil {
    panic(err)
}

然后輸出(在Go Playground上試試):

2018-05-11 00:00:00 +0530 +0530
2018-05-11 00:00:00 +0000 UTC
1525977000
1525996800

另一種選擇是使用time.FixedZone()自己構造IST ,並使用time.ParseInLocation() ,傳遞我們的手動IST位置:

ist := time.FixedZone("IST", 330*60) // +5:30
t, err := time.ParseInLocation("2006-01-02 MST", "2018-05-11 IST", ist)

輸出將是(在Go Playground上嘗試):

2018-05-11 00:00:00 +0530 IST
2018-05-11 00:00:00 +0000 UTC
1525977000
1525996800

另一種選擇是加爾各答市加載印度IST區:

loc, err := time.LoadLocation("Asia/Kolkata")
if err != nil {
    panic(err)
}

哪個會產生相同的輸出。 Go Playground嘗試一下。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM