want to change time duration is seconds but don't want to give hours every time (hrs as optional)
package main
import (
"fmt"
)
func main() {
t1 := "01:30"
seconds, _ := ConvertTimeFormat(t1) // not working fine for this
fmt.Println(seconds)
t2 := "01:01:15"
second, _ := ConvertTimeFormat(t2) // working fine for this
fmt.Println(second)
}
func ConvertTimeFormat(st string) (int, error) {
var h, m, s int
n, err := fmt.Sscanf(st, "%d:%d:%d", &h, &m, &s)
fmt.Print(n, err)
if err != nil || n != 3 {
return 0, err
}
return h*3600 m*60 s, nil
}
CodePudding user response:
Your code is buggy, since you always expect 3 values in the Scanf func.
Try to parse it another way, like:
package main
import (
"errors"
"fmt"
"strconv"
"strings"
)
func main() {
t1 := "01:30"
seconds, _ := ConvertTimeFormat(t1) // not working fine for this
fmt.Println(seconds)
t2 := "01:01:15"
second, _ := ConvertTimeFormat(t2) // working fine for this
fmt.Println(second)
}
func ConvertTimeFormat(st string) (int, error) {
var sh, sm, ss string
parts := strings.Split(st, ":")
switch len(parts) {
case 2:
sm = parts[0]
ss = parts[1]
case 3:
sh = parts[0]
sm = parts[1]
ss = parts[2]
default:
return 0, errors.New("Invalid format")
}
var (
h, m, s int
err error
)
if sh != "" {
h, err = strconv.Atoi(sh)
if err != nil {
return 0, err
}
}
m, err = strconv.Atoi(sm)
if err != nil {
return 0, err
}
s, err = strconv.Atoi(ss)
if err != nil {
return 0, err
}
return h*3600 m*60 s, nil
}
Another solution is to handle the error and try to parse it in the another format:
func ConvertTimeFormat(st string) (int, error) {
var h, m, s int
_, err := fmt.Sscanf(st, "%d:%d:%d", &h, &m, &s)
fmt.Println(h, m, s, err)
if err != nil {
h, m, s = 0, 0, 0
_, err = fmt.Sscanf(st, "%d:%d", &m, &s)
if err != nil {
return 0, err
}
}
return h*3600 m*60 s, nil
}
CodePudding user response:
Split input string at ":" and reverse iterate.
Multiply fields by 1, 60 or 3600 as per position
Add to seconds
Code
var mult = []int{1, 60, 60 * 60}
func ConvertTimeFormat(timeStr string) (int, error) {
var secs int
slice := strings.Split(timeStr, ":")
arrlen := len(slice)// Check length <=3 here
for i := arrlen - 1; i >= 0; i-- {
elem, err := strconv.Atoi(slice[i])
if err != nil {
return -1, fmt.Errorf("error parsing [%s] in [%s] [%v]",
slice[i], timeStr, err)
}
secs = (elem * mult[arrlen-i-1])
}
return secs, nil
}
Erroneous strings "", ":", ":20", "str:30, "::"
etc will be reported by Atoi()
Edit:
Could also use multiplier instead of array, would be extra multiplication operation.
func ConvertTimeFormat(timeStr string) (int, error) {
multiplier := 1
for i := arrlen - 1; i >= 0; i-- {
...
secs = (elem * multiplier)
multiplier *= 60
}
return secs, nil
}
CodePudding user response:
maybe it's more easier to understand and rewrite by yourself. using official package time .
func main() {
t1 := "01:30"
backSeconds(t1)
t2 := "01:01:15"
backSeconds(t2)
// input: 01:30 ----deal: 01m30s ----result: 90
// input: 01:01:15 ----deal: 01h01m15s ----result: 3675
}
func backSeconds(str string) {
deal := preDeal(str)
parse, err := time.ParseDuration(deal)
if err != nil {
log.Println(err)
}
fmt.Println("input: ", str, "----deal: ", deal, "----result: ", parse.Seconds())
}
func preDeal(str string) string {
list := strings.Split(str, ":")
var build strings.Builder
tType := []string{"s", "m", "h"}
j := len(list) - 1
for i := 0; i < len(list); i {
build.WriteString(list[i] tType[j-i])
}
return build.String()
}