如果我们将“一天中的秒数”定义为“自午夜以来经过的秒数”,那么即使在 daylight saving time 发生的日子里也能得到正确的结果,我们应该从给定时间中减去代表午夜的时间。为此,我们可以使用Time.Sub()。
func daySeconds(t time.Time) int {
year, month, day := t.Date()
t2 := time.Date(year, month, day, 0, 0, 0, 0, t.Location())
return int(t.Sub(t2).Seconds())
}
测试它:
for _, t := range []time.Time{
time.Date(2019, 1, 1, 0, 0, 30, 0, time.UTC),
time.Date(2019, 1, 1, 0, 1, 30, 0, time.UTC),
time.Date(2019, 1, 1, 0, 12, 30, 0, time.UTC),
time.Date(2019, 1, 1, 12, 12, 30, 0, time.UTC),
} {
fmt.Println(daySeconds(t))
}
输出(在Go Playground上试试):
30
90
750
43950
让我们看看当夏令时发生时这个函数如何给出正确的结果。在匈牙利,2018 年 3 月 25 日是02:00:00 时钟拨快 1 小时的日子,从2 am 到3 am。
loc, err := time.LoadLocation("CET")
if err != nil {
fmt.Println(err)
return
}
t := time.Date(2018, 3, 25, 0, 0, 30, 0, loc)
fmt.Println(t)
fmt.Println(daySeconds(t))
t = t.Add(2 * time.Hour)
fmt.Println(t)
fmt.Println(daySeconds(t))
这个输出(在Go Playground上试试):
2018-03-25 00:00:30 +0100 CET
30
2018-03-25 03:00:30 +0200 CEST
7230
我们打印一个时间为午夜后 30 秒的daySeconds,当然是30。然后我们将时间加 2 小时(2 小时 = 2*3600 秒 = 7200),这个新时间的daySeconds 将正确地为7200 + 30 = 7230,即使时间改变了 3 小时。