Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Golang parse time.Duration

I would like to parse time.Duration. The duration is "PT15M" (string/bytes) and would like to convert it to a valid time.Duration.


If this were a time.Time thing, I would use:

t, err := time.Parse(time.RFC3339Nano, "2013-06-05T14:10:43.678Z")

But this doesn't exist (ParseDuration only takes one parameter):

d, err := time.ParseDuration(time.RFC3339Nano, "PT15M")


How can I parse this ISO 8601 duration?

like image 833
Etienne Bruines Avatar asked Jan 24 '15 13:01

Etienne Bruines


People also ask

How do you parse time in go?

We can parse any time by using time. Parse function which takes our time string and format in which our string is written as input and if there is no error in our format, it will return a Golang time object.

What does time duration do in Golang?

Duration has a base type int64. Duration represents the elapsed time between two instants as an int64 nanosecond count”. The maximum possible nanosecond representation is up to 290 years.

What is time second in Golang?

Return Value: It returns the second offset within the minute as provided by “t”. Example 1: // Golang program to illustrate the usage of. // Time.Second() function. // Including main package.

What is Unix time in Golang?

The Time. Unix() function in Go language is used to yield “t” as a Unix time that is the number of seconds passed from January 1, 1970, in UTC and the output here doesn't rely upon the location connected with t. Moreover, this function is defined under the time package.


1 Answers

It's not exactly "out of the box" but a regular expression does the job:

package main

import "fmt"
import "regexp"
import "strconv"
import "time"

func main() {
    fmt.Println(ParseDuration("PT15M"))
    fmt.Println(ParseDuration("P12Y4MT15M"))
}

func ParseDuration(str string) time.Duration {
    durationRegex := regexp.MustCompile(`P(?P<years>\d+Y)?(?P<months>\d+M)?(?P<days>\d+D)?T?(?P<hours>\d+H)?(?P<minutes>\d+M)?(?P<seconds>\d+S)?`)
    matches := durationRegex.FindStringSubmatch(str)

    years := ParseInt64(matches[1])
    months := ParseInt64(matches[2])
    days := ParseInt64(matches[3])
    hours := ParseInt64(matches[4])
    minutes := ParseInt64(matches[5])
    seconds := ParseInt64(matches[6])

    hour := int64(time.Hour)
    minute := int64(time.Minute)
    second := int64(time.Second)
    return time.Duration(years*24*365*hour + months*30*24*hour + days*24*hour + hours*hour + minutes*minute + seconds*second)
}

func ParseInt64(value string) int64 {
    if len(value) == 0 {
        return 0
    }
    parsed, err := strconv.Atoi(value[:len(value)-1])
    if err != nil {
        return 0
    }
    return int64(parsed)
}
like image 144
Régis B. Avatar answered Oct 18 '22 10:10

Régis B.