Difference between two time.Time objects

105,602

Solution 1

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:

golang time.Since() with months and years

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

Solution 2

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

Solution 3

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
Share:
105,602
Hemant Bhargava
Author by

Hemant Bhargava

Updated on December 17, 2021

Comments

  • Hemant Bhargava
    Hemant Bhargava over 2 years

    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.

  • Hemant Bhargava
    Hemant Bhargava over 7 years
    Okay, Thanks for the quick answer. I did it: var duration time.Duration = trip.EndTime.Sub(trip.StartTime) fmt.Println("Time difference: Minutes", duration.Minutes(), "Seconds: ", duration.Seconds()) But this does not seem to be giving the right numbers.
  • Shmulik Klein
    Shmulik Klein over 7 years
    What is trip.EndTime\StartTime ?
  • Hemant Bhargava
    Hemant Bhargava over 7 years
    Sorry! Think of it as: t1 = trip.StartTime t2 = trip.EndTime
  • Shmulik Klein
    Shmulik Klein over 7 years
    It is OK, but how does it implemented ?
  • Hemant Bhargava
    Hemant Bhargava over 7 years
    Implemented what? I did not write anything else than above two lines for the duration.
  • Hemant Bhargava
    Hemant Bhargava over 7 years
    Bang on! Thank you.
  • Hemant Bhargava
    Hemant Bhargava over 7 years
    How about if I say I need only hours or minutes?
  • Hemant Bhargava
    Hemant Bhargava over 7 years
    As I said, think of trip.Starttime and trip.EndTime as t1 and t2 respectively.
  • Hemant Bhargava
    Hemant Bhargava over 7 years
    Alright. Thanks for the edit. In your code, in case I need to get only hours/minutes, then?
  • Shmulik Klein
    Shmulik Klein over 7 years
    Then just use fmt.Printf("The hours difference is: %d", t1.Sub(t2).Hours()) or fmt.Printf("The minutes difference is: %d", t1.Sub(t2).Minutes())
  • icza
    icza over 7 years
    @HemantBhargava Then use a different layout string, one that only contains hours and minutes: out.Format("15:04")
  • Hemant Bhargava
    Hemant Bhargava over 7 years
    This is not working. 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")) This outputs : 568.3333333333334 09:90 Which is not correct.
  • icza
    icza over 7 years
    @HemantBhargava Yes of course because "15:30" is an invalid layout string. Please take the time and read the doc at Time.Format() to know what the layout string is. Using out.Format("15:04:05") outputs 09:28:20 which is correct. If you only need hour+min, then use out.Format("15:04") which outputs 09:28, as you can see this on the Go Playground.
  • jk-kim
    jk-kim over 6 years
    leap seconds considerations and data type consideration? this is a $1000 answer to $10 question...