Skip to content

Commit

Permalink
add ParseDuration() util
Browse files Browse the repository at this point in the history
  • Loading branch information
tj committed Nov 7, 2017
1 parent fc1ec7a commit ddff143
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 0 deletions.
24 changes: 24 additions & 0 deletions internal/util/util.go
Expand Up @@ -287,3 +287,27 @@ func Milliseconds(d time.Duration) int {
func MillisecondsSince(t time.Time) int {
return int(time.Since(t) / time.Millisecond)
}

// ParseDuration string with day and month approximation support.
func ParseDuration(s string) (d time.Duration, err error) {
r := strings.NewReader(s)

switch {
case strings.HasSuffix(s, "d"):
var v float64
_, err = fmt.Fscanf(r, "%fd", &v)
d = time.Duration(v * float64(24*time.Hour))
case strings.HasSuffix(s, "mo"):
var v float64
_, err = fmt.Fscanf(r, "%fmo", &v)
d = time.Duration(v * float64(30*24*time.Hour))
case strings.HasSuffix(s, "M"):
var v float64
_, err = fmt.Fscanf(r, "%fM", &v)
d = time.Duration(v * float64(30*24*time.Hour))
default:
d, err = time.ParseDuration(s)
}

return
}
37 changes: 37 additions & 0 deletions internal/util/util_test.go
Expand Up @@ -3,6 +3,7 @@ package util
import (
"os/exec"
"testing"
"time"

"github.com/tj/assert"
)
Expand All @@ -26,3 +27,39 @@ func TestExitStatus(t *testing.T) {
assert.Equal(t, "5", code)
})
}

func TestParseDuration(t *testing.T) {
t.Run("day", func(t *testing.T) {
v, err := ParseDuration("1d")
assert.NoError(t, err, "parsing")
assert.Equal(t, time.Hour*24, v)
})

t.Run("day with faction", func(t *testing.T) {
v, err := ParseDuration("1.5d")
assert.NoError(t, err, "parsing")
assert.Equal(t, time.Duration(float64(time.Hour*24)*1.5), v)
})

t.Run("month", func(t *testing.T) {
v, err := ParseDuration("1mo")
assert.NoError(t, err, "parsing")
assert.Equal(t, time.Hour*24*30, v)

v, err = ParseDuration("1M")
assert.NoError(t, err, "parsing")
assert.Equal(t, time.Hour*24*30, v)
})

t.Run("month with faction", func(t *testing.T) {
v, err := ParseDuration("1.5mo")
assert.NoError(t, err, "parsing")
assert.Equal(t, time.Duration(float64(time.Hour*24*30)*1.5), v)
})

t.Run("default", func(t *testing.T) {
v, err := ParseDuration("15m")
assert.NoError(t, err, "parsing")
assert.Equal(t, 15*time.Minute, v)
})
}

0 comments on commit ddff143

Please sign in to comment.