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>
This commit is contained in:
Mihai Parparita 2022-09-28 16:37:31 -07:00 committed by Mihai Parparita
parent 44f13d32d7
commit 9214b293e3
2 changed files with 47 additions and 0 deletions

View File

@ -8,6 +8,8 @@ package tstime
import (
"errors"
"fmt"
"strconv"
"strings"
"sync"
"time"
@ -141,3 +143,25 @@ func Parse3339(s string) (time.Time, error) {
func Parse3339B(b []byte) (time.Time, error) {
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)
}

View File

@ -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) {
run := func(in string) func(*testing.B) {
return func(b *testing.B) {