Skip to content

Commit

Permalink
feat: add time helpers
Browse files Browse the repository at this point in the history
Signed-off-by: Techno Freak <freak12techno@gmail.com>
  • Loading branch information
freak12techno committed Feb 13, 2024
1 parent f69a508 commit fe8dec6
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 0 deletions.
71 changes: 71 additions & 0 deletions template/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@ package template

import (
"bytes"
"fmt"
tmplhtml "html/template"
"io"
"math"
"net/url"
"path"
"path/filepath"
"regexp"
"sort"
"strconv"
"strings"
tmpltext "text/template"
"time"
Expand Down Expand Up @@ -192,6 +195,74 @@ var DefaultFuncs = FuncMap{
"stringSlice": func(s ...string) []string {
return s
},
"since": time.Since,
"humanizeDuration": func(i interface{}) (string, error) {
v, err := convertToFloat(i)
if err != nil {
return "", err
}

if math.IsNaN(v) || math.IsInf(v, 0) {
return fmt.Sprintf("%.4g", v), nil
}
if v == 0 {
return fmt.Sprintf("%.4gs", v), nil
}
if math.Abs(v) >= 1 {
sign := ""
if v < 0 {
sign = "-"
v = -v
}
duration := int64(v)
seconds := duration % 60
minutes := (duration / 60) % 60
hours := (duration / 60 / 60) % 24
days := duration / 60 / 60 / 24
// For days to minutes, we display seconds as an integer.
if days != 0 {
return fmt.Sprintf("%s%dd %dh %dm %ds", sign, days, hours, minutes, seconds), nil
}
if hours != 0 {
return fmt.Sprintf("%s%dh %dm %ds", sign, hours, minutes, seconds), nil
}
if minutes != 0 {
return fmt.Sprintf("%s%dm %ds", sign, minutes, seconds), nil
}
// For seconds, we display 4 significant digits.
return fmt.Sprintf("%s%.4gs", sign, v), nil
}
prefix := ""
for _, p := range []string{"m", "u", "n", "p", "f", "a", "z", "y"} {
if math.Abs(v) >= 1 {
break
}
prefix = p
v *= 1000
}
return fmt.Sprintf("%.4g%ss", v, prefix), nil
},
}

func convertToFloat(i interface{}) (float64, error) {
switch v := i.(type) {
case float64:
return v, nil
case string:
return strconv.ParseFloat(v, 64)
case int:
return float64(v), nil
case uint:
return float64(v), nil
case int64:
return float64(v), nil
case uint64:
return float64(v), nil
case time.Duration:
return v.Seconds(), nil
default:
return 0, fmt.Errorf("can't convert %T to float", v)
}
}

// Pair is a key/value string pair.
Expand Down
47 changes: 47 additions & 0 deletions template/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,53 @@ func TestTemplateExpansion(t *testing.T) {
},
exp: "[key2 key4]",
},
{
title: "Template using HumanizeDuration - seconds - float64",
in: "{{ range . }}{{ humanizeDuration . }}:{{ end }}",
data: []float64{0, 1, 60, 3600, 86400, 86400 + 3600, -(86400*2 + 3600*3 + 60*4 + 5), 899.99},
exp: "0s:1s:1m 0s:1h 0m 0s:1d 0h 0m 0s:1d 1h 0m 0s:-2d 3h 4m 5s:14m 59s:",
},
{
title: "Template using HumanizeDuration - seconds - string.",
in: "{{ range . }}{{ humanizeDuration . }}:{{ end }}",
data: []string{"0", "1", "60", "3600", "86400"},
exp: "0s:1s:1m 0s:1h 0m 0s:1d 0h 0m 0s:",
},
{
title: "Template using HumanizeDuration - subsecond and fractional seconds - float64.",
in: "{{ range . }}{{ humanizeDuration . }}:{{ end }}",
data: []float64{.1, .0001, .12345, 60.1, 60.5, 1.2345, 12.345},
exp: "100ms:100us:123.5ms:1m 0s:1m 0s:1.234s:12.35s:",
},
{
title: "Template using HumanizeDuration - subsecond and fractional seconds - string.",
in: "{{ range . }}{{ humanizeDuration . }}:{{ end }}",
data: []string{".1", ".0001", ".12345", "60.1", "60.5", "1.2345", "12.345"},
exp: "100ms:100us:123.5ms:1m 0s:1m 0s:1.234s:12.35s:",
},
{
title: "Template using HumanizeDuration - string with error.",
in: `{{ humanizeDuration "one" }}`,
fail: true,
},
{
title: "Template using HumanizeDuration - int.",
in: "{{ range . }}{{ humanizeDuration . }}:{{ end }}",
data: []int{0, -1, 1, 1234567},
exp: "0s:-1s:1s:14d 6h 56m 7s:",
},
{
title: "Template using HumanizeDuration - uint.",
in: "{{ range . }}{{ humanizeDuration . }}:{{ end }}",
data: []uint{0, 1, 1234567},
exp: "0s:1s:14d 6h 56m 7s:",
},
{
title: "Template using since",
in: "{{ . | since | humanizeDuration }}",
data: time.Now().Add(-1 * time.Hour),
exp: "1h 0m 0s",
},
} {
tc := tc
t.Run(tc.title, func(t *testing.T) {
Expand Down

0 comments on commit fe8dec6

Please sign in to comment.