diff --git a/template/template.go b/template/template.go index fc388be5dd..dcb6e280ed 100644 --- a/template/template.go +++ b/template/template.go @@ -339,6 +339,14 @@ var DefaultFuncs = FuncMap{ "mustToDate": func(layout, s string) (time.Time, error) { return time.ParseInLocation(layout, s, time.UTC) }, + // addDuration parses ds as a Go duration, adds it to t, and returns the resulting Unix milliseconds. + "addDuration": func(t time.Time, ds string) (int64, error) { + d, err := time.ParseDuration(ds) + if err != nil { + return 0, err + } + return t.Add(d).UnixMilli(), nil + }, "toJson": func(v any) (string, error) { bytes, err := json.Marshal(v) if err != nil { diff --git a/template/template_test.go b/template/template_test.go index 9c884ea77d..31823e5ed1 100644 --- a/template/template_test.go +++ b/template/template_test.go @@ -902,6 +902,16 @@ func TestTemplateFuncs(t *testing.T) { title: "Template using mustToDate with invalid input returns error", in: `{{ mustToDate "2006-01-02" "not-a-date" }}`, expErr: `template: :1:3: executing "" at : error calling mustToDate: parsing time "not-a-date" as "2006-01-02": cannot parse "not-a-date" as "2006"`, + }, { + title: "Template using addDuration with valid input", + in: `{{ addDuration . "90m" }}`, + data: time.Unix(0, 0).UTC(), + exp: "5400000", + }, { + title: "Template using addDuration with invalid input returns error", + in: `{{ addDuration . "not-a-duration" }}`, + data: time.Unix(0, 0).UTC(), + expErr: `template: :1:3: executing "" at : error calling addDuration: time: invalid duration "not-a-duration"`, }} { t.Run(tc.title, func(t *testing.T) { wg := sync.WaitGroup{}