【问题标题】:Difference between two time.Time objects两个 time.Time 对象之间的差异
【发布时间】:2017-03-08 17:17:43
【问题描述】:

对“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,但无法从中获得任何信息。

【问题讨论】:

    标签: datetime go time


    【解决方案1】:

    实际上,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
    • 可以,但是怎么实现的呢?
    • 实现了什么?在此期间,我除了以上两行之外没有写任何其他内容。
    【解决方案2】:

    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))
            }
    
        }
    }
    
    
    
    

    【讨论】:

      【解决方案3】:

      补充 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 美元答案...
      【解决方案4】:

      您可以使用Time.Sub() 来获取两个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 上看到这一点。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-16
      • 2013-04-12
      • 2022-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-04
      相关资源
      最近更新 更多