Difference between two time.Time objects

huangapple go评论87阅读模式
英文:

Difference between two time.Time objects

问题

对于两个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,但是可能无法理解。

英文:

Very new to the 'Go'. Question might be basic one.

I have two time.Time objects and I want to get the difference between the two in terms of hours/minutes/seconds. Lets say:

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

In above case, since the difference is 0. It should give me 00:00:00. Consider another case:

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

In this case, difference would be 00:05:41. I looked at the https://godoc.org/time but could not make anything out of it.

答案1

得分: 152

你可以使用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上尝试这些示例。

当然,这只适用于时间差小于一天的情况。如果差异可能更大,那就是另外一回事了。结果必须包括天、月和年。复杂性会显著增加。请参考这个问题的详细解答:

https://stackoverflow.com/questions/36530251/golang-time-since-with-months-and-years/36531443#36531443

那里提供的解决方案通过展示具有以下签名的函数来解决这个问题:

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

即使你的时间在24小时内(此时yearmonthday将为0),你也可以使用这个函数。

英文:

You may use Time.Sub() to get the difference between the 2 time.Time values, result will be a value of time.Duration.

When printed, a time.Duration formats itself "intelligently":

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

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

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

Output:

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

If you want the time format HH:mm:ss, you may constuct a time.Time value and use its Time.Format() method like this:

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

Output:

00:05:41

Try the examples on the Go Playground.

Of course this will only work if the time difference is less than a day. If the difference may be bigger, then it's another story. The result must include days, months and years. Complexity increases significnatly. See this question for details:

https://stackoverflow.com/questions/36530251/golang-time-since-with-months-and-years/36531443#36531443

The solution presented there solves this issue by showing a function with signature:

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

You may use that even if your times are within 24 hours (in which case year, month and day will be 0).

答案2

得分: 38

实际上,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())
}
英文:

Actually, the time package's documentation does discuss it:

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

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

You should produce a Duration object using Sub() and then use one of the 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())
}

答案3

得分: 6

有两种常见的方法:

第一种方法比较直接:

startTime := time.Now()
diff := time.Now().Sub(startTime)

第二种方法稍微简短一些:

startTime := time.Now()
diff := time.Since(startTime)
英文:

There are 2 common ways:

straight forward one:

startTime := time.Now()
diff := time.Now().Sub(startTime)

shorter one (a bit):

startTime := time.Now()
diff := time.Since(startTime)

答案4

得分: 4

为了补充Shmulik Klein的答案:

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

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, "小时", ms, "分钟", ss, "秒")
}

2 小时 36 分钟 25.999999999999375 秒

注意:

  • 由于使用了float64类型,存在轻微的精度损失
  • 我们忽略闰秒,并假设每分钟有60秒
英文:

To complement Shmulik Klein's answer:

Another way to calculate disjoint hours/minutes/seconds out of a time.Duration:

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 hours 36 minutes 25.999999999999375 seconds

note:

  • slight precision loss due to the use of the float64 type
  • we ignore leap seconds and assume every minute has 60 seconds

答案5

得分: 0

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

	}
}

以上是一个Go语言的示例代码,它定义了一个TimeAsString函数,用于将时间转换为字符串格式。在main函数中,它使用time.Tick函数创建了一个定时器,每隔33毫秒触发一次。在每次定时器触发时,它计算自上次触发以来的时间差,并将时间累加到mytime变量上,然后调用TimeAsString函数将时间转换为字符串并打印出来。

英文:

DEMO


package main

import (
	&quot;fmt&quot;
	&quot;math&quot;
	&quot;time&quot;
)

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(&quot;%v:%v:%v&quot;, hours, minutes, seconds)
}

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

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

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

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

	}
}



huangapple
  • 本文由 发表于 2016年10月26日 19:03:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/40260599.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定