Parse duration with time.Parse using time.Sub

I was needed to parse time.Duration in format like HH:MM:SS

It’s very handy to parse it with time.Parse("15:04:05", stringToParse), but then I need to get duration. There is another handy method for this time.Sub.

So basically this code should work:

func parseDur(s string) time.Duration {
	t, _ := time.Parse("15:04:05", o)
	return t.Sub(time.Time{})
}

But this code returns parsed duration -1 year. I can fix it returning

t.AddDate(1, 0, 0).Sub(time.Time{})

but that looks so ugly!

It appears that time.Time{} returns
0001-01-01 00:00:00 +0000 UTC
but time.Parse() by default returns
0000-01-01 00:00:00 +0000 UTC

Isn’t it design flaw? Should it be fixed?

1 Like

No

The zero value of type Time is January 1, year 1, 00:00:00.000000000 UTC. As this time is unlikely to come up in practice, the IsZero method gives a simple way of detecting a time that has not been initialized explicitly.


package main

import (
	"fmt"
	"time"
)

const clockLayout = "15:04:05"

var clockZero, _ = time.Parse(clockLayout, "00:00:00")

func clockDuration(clock string) (time.Duration, error) {
	c, err := time.Parse(clockLayout, clock)
	if err != nil {
		return 0, err
	}
	return c.Sub(clockZero), nil
}

func main() {
	d, err := clockDuration("01:02:03")
	fmt.Println(d, err)
}

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

1h2m3s <nil>


package main

import (
	"fmt"
	"time"
)

func clockDuration(clock string) (time.Duration, error) {
	c, err := time.Parse("15:04:05", clock)
	if err != nil {
		return 0, err
	}
	h, m, s := c.Clock()
	d := time.Duration(h)*time.Hour +
		time.Duration(m)*time.Minute +
		time.Duration(s)*time.Second
	return d, nil
}

func main() {
	d, err := clockDuration("01:02:03")
	fmt.Println(d, err)
}

https://play.golang.org/p/3QdTpywFQxV

1h2m3s <nil>

1 Like

Thank you for great solutions for this problem! First one seems more elegant imho.

I understand that zero value of time is January 1, year 1, 00:00:00.000000000 UTC, but why time.Parse return doesn’t based on this zero value?

The zero value of type Time is January 1, year 1, 00:00:00.000000000 UTC. As this time is unlikely to come up in practice, the IsZero method gives a simple way of detecting a time that has not been initialized explicitly.

If the year is not applicable, as in your case, zero is the obvious value for year. The zero value for time.Time is an unlikely value.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.