Home > database >  convering 00:33 to duration in golang
convering 00:33 to duration in golang

Time:02-03

I have a string "12:34" that is "MM:SS" format and I want to convert it to a time.Duration. Wasted too much time on this already. What am I doing wrong in this code:

package main

import (
    "fmt"
    "strings"
    "time"
)

func parseDuration(input string) (time.Duration, error) {
    var layout string
    if strings.Count(input, ":") == 1 {
        layout = "04:05"
    } else {
        layout = "15:04:05"
    }
    t, err := time.Parse(layout, input)
    if err != nil {
        return 0, err
    }
    return t.Sub(time.Time{}), nil
}

func main() {
    input := "00:04"
    duration, err := parseDuration(input)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(int(duration.Seconds())) // I should get 4 but I get -31622396

}

https://go.dev/play/p/A-eHc-EPTrd

CodePudding user response:

The issue is with the line return t.Sub(time.Time{}), nil. You're subtracting the zero value of time.Time from t, which is equivalent to subtracting the Unix epoch time from t.

To get the duration from the string, you should use time.ParseDuration() instead:

duration, err := time.ParseDuration(input)
if err != nil {
    fmt.Println(err)
    return
}
fmt.Println(int(duration.Seconds()))

This will correctly parse the duration in the string, and you'll get the expected output of 4.

CodePudding user response:

The zero value of type Time is January 1, year 1, 00:00:00.000000000 UTC.

func parseDuration(input string) (time.Duration, error) {
    var layout string
    if strings.Count(input, ":") == 1 {
        layout = "04:05"
    } else {
        layout = "15:04:05"
    }
    t, err := time.Parse(layout, input)
    if err != nil {
        return 0, err
    }
    return t
}

fmt.Println(time.Time{})
// this prints 0001-01-01 00:00:00  0000 UTC
fmt.Println(parseDuration("00:04"))
// this prints 0000-01-01 00:00:04  0000 UTC

In your case, you should define a start object instead of using time.Time{} directly. For example,

package main

import (
    "fmt"
    "strings"
    "time"
)

var origin = time.Date(0, 1, 1, 0, 0, 0, 0, time.UTC)

func parseDuration(input string) (time.Duration, error) {
    var layout string
    if strings.Count(input, ":") == 1 {
        layout = "04:05"
    } else {
        layout = "15:04:05"
    }
    t, err := time.Parse(layout, input)
    if err != nil {
        return 0, err
    }
    return t.Sub(origin), nil
}

func main() {
    input := "00:04"
    duration, err := parseDuration(input)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(duration.String()) // this prints 4s

}

https://go.dev/play/p/maGeyA0KWd3

  •  Tags:  
  • go
  • Related