如何查看当前当地时间是否为夏令时?

时间:2018-10-29 13:34:34

标签: go

例如,在Ruby中,有Time#dst?函数,在夏令时的情况下返回true。是否有Go标准库API调用可以做到这一点?

3 个答案:

答案 0 :(得分:1)

Location API不会导出时区的DST值。这是几年前在golang-nuts forum中提出的。一种建议是将1月1日时区偏移量与7月1日时区偏移量进行比较。使用此方法发布了有效的solution。一个警告是,goplay的本地时间错误,因此,如果在本地运行它,它不会正确报告信息。您可以在本地运行它以验证它是否有效。

另一种方法是通过reflect包使用反射。我为此写的解决方案here可用。这种方法有很多问题。

编辑:确实应该使用cacheZone,但是对区域进行线性搜索以找到匹配的区域。由于某些时区共享名称和偏移量,因此可能导致错误。正确的方法是查看cacheZone并使用(如果已设置)。否则,您将需要查看zoneTrans或至少查看lookup(int64)的实现方式。

答案 1 :(得分:1)

您可以推断结果。例如,

package main

import (
    "fmt"
    "time"
)

// isTimeDST returns true if time t occurs within daylight saving time
// for its time zone.
func isTimeDST(t time.Time) bool {
    // If the most recent (within the last year) clock change
    // was forward then assume the change was from std to dst.
    hh, mm, _ := t.UTC().Clock()
    tClock := hh*60 + mm
    for m := -1; m > -12; m-- {
        // assume dst lasts for least one month
        hh, mm, _ := t.AddDate(0, m, 0).UTC().Clock()
        clock := hh*60 + mm
        if clock != tClock {
            if clock > tClock {
                // std to dst
                return true
            }
            // dst to std
            return false
        }
    }
    // assume no dst
    return false
}

func main() {
    pstLoc, err := time.LoadLocation("America/Los_Angeles")
    if err != nil {
        fmt.Println(err)
        return
    }

    utc := time.Date(2018, 10, 29, 14, 0, 0, 0, time.UTC)
    fmt.Println(utc, utc.Location(), ": DST", isTimeDST(utc))
    local := utc.In(time.Local)
    fmt.Println(local, local.Location(), ": DST", isTimeDST(local))
    pst := utc.In(pstLoc)
    fmt.Println(pst, pst.Location(), ": DST", isTimeDST(pst))

    utc = utc.AddDate(0, 3, 0)
    fmt.Println(utc, utc.Location(), ": DST", isTimeDST(utc))
    local = utc.In(time.Local)
    fmt.Println(local, local.Location(), ": DST", isTimeDST(local))
    pst = utc.In(pstLoc)
    fmt.Println(pst, pst.Location(), ": DST", isTimeDST(pst))
}

输出:

2018-10-29 14:00:00 +0000 UTC UTC : DST false
2018-10-29 10:00:00 -0400 EDT Local : DST true
2018-10-29 07:00:00 -0700 PDT America/Los_Angeles : DST true
2019-01-29 14:00:00 +0000 UTC UTC : DST false
2019-01-29 09:00:00 -0500 EST Local : DST false
2019-01-29 06:00:00 -0800 PST America/Los_Angeles : DST false

答案 2 :(得分:0)

在紧要关头,这应该可以解决问题:

func inDST(t time.Time) bool {

    jan1st := time.Date(t.Year(), 1, 1, 0, 0, 0, 0, t.Location()) // January 1st is always outside DST window

    _, off1 := t.Zone()
    _, off2 := jan1st.Zone()

    return off1 != off2
}