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:
parent
44f13d32d7
commit
9214b293e3
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue