【问题标题】:How to get the seconds of day [closed]如何获得一天中的秒数[关闭]
【发布时间】:2019-07-28 02:46:54
【问题描述】:

如何在 Go 中获取一天中的秒数 (1 - 86400)?

就像http://joda-time.sourceforge.net/apidocs/org/joda/time/base/AbstractDateTime.html#getSecondOfDay()

更新/澄清

  • 想要相当于 golang 中的 joda/SecondOfDay
  • 预计在一天结束时从 0 点和 86400 点开始
  • 在 golang 中重写 java 开源函数时需要,该函数又使用 joda/secondOfDay
  • 谷歌搜索“24 小时到秒”得到 86400
  • 在问问题时,我只能想到 now.Unix()-yesterdayMidnight.Unix() 并且没有想到简单的公认答案
  • 显然没有考虑夏令时
  • 想看看是否有一些内置函数或流行/标准库

【问题讨论】:

  • 你试过什么?包括您的代码。你遇到了什么问题?
  • "一天中的秒数 (1 - 86400)。"在夏令时转换期间,一天的时间多于或少于 86,400 秒。

标签: go time


【解决方案1】:

如果我们将“一天中的秒数”定义为“自午夜以来经过的秒数”,那么即使在 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 am3 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 小时。

【讨论】:

    【解决方案2】:

    注意: 此函数返回 (0 - 86399) 范围内的标称秒数。如果您正在寻找“自午夜以来经过的秒数”,由于夏令时可能不在 (0 - 86399) 范围内,请参阅@icza 的答案。

    更新: 另请注意,该问题涉及 Joda Time 实现,根据Joda Time getSecondOfDay on DST switch day,它似乎对应于名义上的实现秒数(如下面我的回答),而不是“自午夜以来经过的秒数”(就像@icza 的回答一样)。

    package main 
    
    import (
        "fmt"
        "time"
    )
    
    func getSecondOfDay(t time.Time) int {
        return 60*60*t.Hour() + 60*t.Minute() + t.Second()
    }
    
    func main() {
        t := time.Now()
        fmt.Println(getSecondOfDay(t))
    }
    

    【讨论】:

    • 这在夏令时发生时不起作用。此外,Time.Truncate() 按时间作为自零时间以来的绝对持续时间运行,因此它也可能返回不正确的结果。
    • 阅读Time.Truncate()的文档。这是一个示例:play.golang.org/p/hAfBrYWNeZ
    • 在夏令时发生的日子里,您仍然有一个选项会给出无效的结果。
    • @perl 正是我的观点。如果时钟倒转,那一天有超过 86400 秒。所以报告更多是正确的答案。
    • @icza:我在我的回答中添加了一条评论以澄清这一点,并参考了您对“自午夜以来的秒数”版本的回答
    猜你喜欢
    • 2015-01-29
    • 1970-01-01
    • 1970-01-01
    • 2021-01-23
    • 1970-01-01
    • 2012-07-11
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    相关资源
    最近更新 更多