ChatGPT解决这个技术问题 Extra ChatGPT

两个 time.Time 对象之间的差异

对“Go”非常陌生。问题可能是基本问题。

我有两个 time.Time 对象,我想在小时/分钟/秒方面得到两者之间的差异。让我们说:

t1 = 2016-09-09 19:09:16 +0530 IST
t2 = 2016-09-09 19:09:16 +0530 IST

在上述情况下,因为差异为 0。它应该给我 00:00:00。考虑另一种情况:

t1 = 2016-09-14 14:12:48 +0530 IST
t2 = 2016-09-14 14:18:29 +0530 IST

在这种情况下,差异将是 00:05:41。我看着https://godoc.org/time,但无法从中做出任何事情。


C
Community

您可以使用 Time.Sub() 来获取 2 个 time.Time 值之间的差异,结果将是 time.Duration 的值。

打印时,time.Duration 会“智能地”格式化自身:

t1 := time.Now()
t2 := t1.Add(time.Second * 341)

fmt.Println(t1)
fmt.Println(t2)

diff := t2.Sub(t1)
fmt.Println(diff)

输出:

2009-11-10 23:00:00 +0000 UTC
2009-11-10 23:05:41 +0000 UTC
5m41s

如果您想要时间格式 HH:mm:ss,您可以构造一个 time.Time 值并使用它的 Time.Format() 方法,如下所示:

out := time.Time{}.Add(diff)
fmt.Println(out.Format("15:04:05"))

输出:

00:05:41

试试 Go Playground 上的示例。

当然,这只有在时差小于一天的情况下才有效。如果差异可能更大,那就是另一回事了。结果必须包括天、月和年。复杂性显着增加。有关详细信息,请参阅此问题:

golang time.Since() with months and years

那里提出的解决方案通过显示一个带有签名的函数来解决这个问题:

func diff(a, b time.Time) (year, month, day, hour, min, sec int)

即使您的时间在 24 小时之内,您也可以使用它(在这种情况下,yearmonthday 将是 0)。


砰!谢谢你。
如果我说我只需要几小时或几分钟呢?
@HemantBhargava 然后使用不同的布局字符串,只包含小时和分钟:out.Format("15:04")
这是行不通的。 t1 := time.Now() t2 := t1.Add(time.Second * 34100) diff := t2.Sub(t1) fmt.Println(diff.Minutes()) out := time.Time{}.Add(diff) fmt.Println(out.Format( "15:30")) 这输出: 568.3333333333334 09:90 这是不正确的。
@HemantBhargava 当然是的,因为 "15:30" 是无效的布局字符串。请花点时间阅读 Time.Format() 处的文档以了解布局字符串是什么。使用 out.Format("15:04:05") 输出 09:28:20 这是正确的。如果您只需要小时+分钟,则使用输出 09:28out.Format("15:04"),您可以在 Go Playground 上看到这一点。
P
Pallav Jha

实际上,time 包的文档确实讨论了它:

https://godoc.org/time#Time.Sub

https://godoc.org/time#Duration.Hours

您应该使用 Sub() 生成一个 Duration 对象,然后使用 Seconds()Minutes()Hours() 之一。

package main

import (
        "fmt"
        "time"
)

func main() {
        t1 := time.Date(1984, time.November, 3, 13, 0, 0, 0, time.UTC)
        t2 := time.Date(1984, time.November, 3, 10, 0, 0, 0, time.UTC)
        fmt.Printf("The hours difference is: %f", t1.Sub(t2).Hours())
}

好的,感谢您的快速答复。我做到了:var duration time.Duration = trip.EndTime.Sub(trip.StartTime) fmt.Println("时差:分钟", duration.Minutes(), "Seconds:", duration.Seconds()) 但这似乎没有给出正确的数字。
trip.EndTime\StartTime 是什么?
对不起!把它想象成: t1 = trip.StartTime t2 = trip.EndTime
没关系,但它是如何实现的?
实施了什么?在此期间,我除了以上两行之外没有写任何其他内容。
t
thwd

为了补充 Shmulik Klein 的回答:

另一种计算时间中不相交的小时/分钟/秒的方法。持续时间:

https://play.golang.org/p/VRoXG5NxLo

package main

import (
    "fmt"
    "math"
    "time"
)

func main() {
    t1 := time.Date(1984, time.November, 3, 13, 0, 0, 0, time.UTC)
    t2 := time.Date(1984, time.November, 3, 10, 23, 34, 0, time.UTC)

    hs := t1.Sub(t2).Hours()

    hs, mf := math.Modf(hs)
    ms := mf * 60

    ms, sf := math.Modf(ms)
    ss := sf * 60

    fmt.Println(hs, "hours", ms, "minutes", ss, "seconds")
}

2 小时 36 分 25.999999999999375 秒

笔记:

由于使用 float64 类型而导致的轻微精度损失

我们忽略闰秒并假设每分钟有 60 秒


闰秒注意事项和数据类型注意事项?这是对 10 美元问题的 1000 美元答案...
S
STEEL

DEMO


package main

import (
    "fmt"
    "math"
    "time"
)

func TimeAsString(dt float64) string {
    time := dt
    hours := math.Floor(time / 3600)
    minutes := math.Ceil(math.Mod(time, 3600)/60) - 1
    seconds := int(time) % 60
    return fmt.Sprintf("%v:%v:%v", hours, minutes, seconds)
}

func main() {
    mytime := 0.0
    last := time.Now()

    tick := time.Tick(33 * time.Millisecond)
    for {

        select {
        case <-tick:
            dt := time.Since(last).Seconds()
            last = time.Now()

            mytime += dt
            fmt.Println(TimeAsString(mytime))
        }

    }
}