tstime: add ParseDuration helper function

More expressive than time.ParseDuration, also accepting d (days) and
w (weeks) literals.

Signed-off-by: Mihai Parparita <mihai@tailscale.com>
pull/5646/head
Mihai Parparita 2 years ago committed by Mihai Parparita
parent 44f13d32d7
commit 9214b293e3

@ -8,6 +8,8 @@ package tstime
import ( import (
"errors" "errors"
"fmt" "fmt"
"strconv"
"strings"
"sync" "sync"
"time" "time"
@ -141,3 +143,25 @@ func Parse3339(s string) (time.Time, error) {
func Parse3339B(b []byte) (time.Time, error) { func Parse3339B(b []byte) (time.Time, error) {
return parse3339m(mem.B(b)) return parse3339m(mem.B(b))
} }
// ParseDuration is more expressive than time.ParseDuration, also accepting d
// (days) and w (weeks) literals.
func ParseDuration(s string) (time.Duration, error) {
for {
end := strings.IndexAny(s, "dw")
if end < 0 {
break
}
start := end - (len(s[:end]) - len(strings.TrimRight(s[:end], "012345789")))
n, err := strconv.Atoi(s[start:end])
if err != nil {
return 0, err
}
hours := 24
if s[end] == 'w' {
hours *= 7
}
s = s[:start] + s[end+1:] + strconv.Itoa(n*hours) + "h"
}
return time.ParseDuration(s)
}

@ -102,6 +102,29 @@ func TestParseInt(t *testing.T) {
} }
} }
func TestParseDuration(t *testing.T) {
tests := []struct {
in string
want time.Duration
}{
{"1h", time.Hour},
{"1d", 24 * time.Hour},
{"1d1d", 48 * time.Hour},
{"1h1d", 25 * time.Hour},
{"1d1h", 25 * time.Hour},
{"1w", 7 * 24 * time.Hour},
{"1w1d1h", 8*24*time.Hour + time.Hour},
{"1w1d1h", 8*24*time.Hour + time.Hour},
{"1y", 0},
{"", 0},
}
for _, tt := range tests {
if got, _ := ParseDuration(tt.in); got != tt.want {
t.Errorf("ParseDuration(%q) = %d; want %d", tt.in, got, tt.want)
}
}
}
func BenchmarkGoParse3339(b *testing.B) { func BenchmarkGoParse3339(b *testing.B) {
run := func(in string) func(*testing.B) { run := func(in string) func(*testing.B) {
return func(b *testing.B) { return func(b *testing.B) {

Loading…
Cancel
Save