Skip to content

Commit

Permalink
Add day suffix support to ParseDurationSecond (#13)
Browse files Browse the repository at this point in the history
* Add day suffix support to ParseDurationSecond

Add support for a "d" suffix that corresponds to 24 hours. Also add
more test cases and slightly refactor the code.

* Revert to ParseInt

* Refactor logic order

* Add test
  • Loading branch information
Jim Kalafut committed Oct 27, 2021
1 parent f277d31 commit 39924fb
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 28 deletions.
24 changes: 13 additions & 11 deletions parseutil/parseutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,20 +105,22 @@ func ParseDurationSecond(in interface{}) (time.Duration, error) {
if inp == "" {
return dur, nil
}
var err error
// Look for a suffix otherwise its a plain second value
if strings.HasSuffix(inp, "s") || strings.HasSuffix(inp, "m") || strings.HasSuffix(inp, "h") || strings.HasSuffix(inp, "ms") {
dur, err = time.ParseDuration(inp)
if err != nil {
return dur, err
}
} else {
// Plain integer
secs, err := strconv.ParseInt(inp, 10, 64)

if v, err := strconv.ParseInt(inp, 10, 64); err == nil {
return time.Duration(v) * time.Second, nil
}

if strings.HasSuffix(inp, "d") {
v, err := strconv.ParseInt(inp[:len(inp)-1], 10, 64)
if err != nil {
return dur, err
}
dur = time.Duration(secs) * time.Second
return time.Duration(v) * 24 * time.Hour, nil
}

var err error
if dur, err = time.ParseDuration(inp); err != nil {
return dur, err
}
case int:
dur = time.Duration(inp) * time.Second
Expand Down
85 changes: 68 additions & 17 deletions parseutil/parseutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,26 +156,77 @@ func Test_ParseCapacityString(t *testing.T) {
}

func Test_ParseDurationSecond(t *testing.T) {
outp, err := ParseDurationSecond("9876s")
if err != nil {
t.Fatal(err)
}
if outp != time.Duration(9876)*time.Second {
t.Fatal("not equivalent")
}
outp, err = ParseDurationSecond("9876")
if err != nil {
t.Fatal(err)
type Test struct {
in interface{}
out time.Duration
invalid bool
}
if outp != time.Duration(9876)*time.Second {
t.Fatal("not equivalent")

tests := []Test{
// Numeric inputs
{in: 9876, out: 9876 * time.Second},
{in: 5.5, out: 5 * time.Second},
{in: 5, out: 5 * time.Second},
{in: 0.9, out: 0 * time.Second},
{in: -5, out: -5 * time.Second},

// String inputs
{in: "9876", out: 9876 * time.Second},
{in: "9876s", out: 9876 * time.Second},
{in: "50ms", out: 50 * time.Millisecond},
{in: "0.5m", out: 30 * time.Second},
{in: "0.5s", out: 500 * time.Millisecond},
{in: "5m", out: 5 * time.Minute},
{in: "6h", out: 6 * time.Hour},
{in: "5d", out: 5 * 24 * time.Hour},
{in: "-5d", out: -5 * 24 * time.Hour},
{in: "05d", out: 5 * 24 * time.Hour},
{in: "500d", out: 500 * 24 * time.Hour},

// JSON Number inputs
{in: json.Number("4352s"), out: 4352 * time.Second},
}
outp, err = ParseDurationSecond(json.Number("4352"))
if err != nil {
t.Fatal(err)

// Invalid inputs
for _, s := range []string{
"5 s",
"5sa",
" 5m",
"5h ",
"5days",
"9876q",
"s20ms",
"10S",
"ad",
"0.5d",
"1.5d",
"d",
"4世",
"s",
"m",
} {
tests = append(tests, Test{
in: s,
invalid: true,
})
}
if outp != time.Duration(4352)*time.Second {
t.Fatal("not equivalent")

for _, test := range tests {
out, err := ParseDurationSecond(test.in)
if test.invalid {
if err == nil {
t.Fatalf("%q: expected error, got nil", test.in)
}
continue
}

if err != nil {
t.Fatal(err)
}

if out != test.out {
t.Fatalf("%q: expected: %q, got: %q", test.in, test.out, out)
}
}
}

Expand Down

0 comments on commit 39924fb

Please sign in to comment.