Skip to content

Commit

Permalink
Add date and tz functions to templates (prometheus#3812)
Browse files Browse the repository at this point in the history
* Add date and tz functions to templates

This commit adds the date and tz functions to templates. This means
users can now format time in a specified format and also change
the timezone to their specific locale.

An example of how these functions work, and can be composed together,
can be seen here:

	{{ .StartsAt | tz "Europe/Paris" | date "15:04:05 MST" }}

Signed-off-by: George Robinson <[email protected]>

---------

Signed-off-by: George Robinson <[email protected]>
  • Loading branch information
grobinson-grafana authored Apr 22, 2024
1 parent cb9724d commit dc1e1a2
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 6 deletions.
2 changes: 2 additions & 0 deletions docs/notifications.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,5 @@ templating.
| join | sep string, s []string | [strings.Join](http://golang.org/pkg/strings/#Join), concatenates the elements of s to create a single string. The separator string sep is placed between elements in the resulting string. (note: argument order inverted for easier pipelining in templates.) |
| safeHtml | text string | [html/template.HTML](https://golang.org/pkg/html/template/#HTML), Marks string as HTML not requiring auto-escaping. |
| stringSlice | ...string | Returns the passed strings as a slice of strings. |
| date | string, time.Time | Returns the text representation of the time in the specified format. For documentation on formats refer to [pkg.go.dev/time](https://pkg.go.dev/time#pkg-constants). |
| tz | string, time.Time | Returns the time in the timezone. For example, Europe/Paris. |
12 changes: 12 additions & 0 deletions template/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,18 @@ var DefaultFuncs = FuncMap{
"stringSlice": func(s ...string) []string {
return s
},
// date returns the text representation of the time in the specified format.
"date": func(fmt string, t time.Time) string {
return t.Format(fmt)
},
// tz returns the time in the timezone.
"tz": func(name string, t time.Time) (time.Time, error) {
loc, err := time.LoadLocation(name)
if err != nil {
return time.Time{}, err
}
return t.In(loc), nil
},
}

// Pair is a key/value string pair.
Expand Down
33 changes: 27 additions & 6 deletions template/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -473,10 +473,11 @@ func TestTemplateFuncs(t *testing.T) {
require.NoError(t, err)

for _, tc := range []struct {
title string
in string
data interface{}
exp string
title string
in string
data interface{}
exp string
expErr string
}{{
title: "Template using toUpper",
in: `{{ "abc" | toUpper }}`,
Expand Down Expand Up @@ -506,6 +507,21 @@ func TestTemplateFuncs(t *testing.T) {
title: "Template using reReplaceAll",
in: `{{ reReplaceAll "ab" "AB" "abc" }}`,
exp: "ABc",
}, {
title: "Template using date",
in: `{{ . | date "2006-01-02" }}`,
data: time.Date(2024, 1, 1, 8, 15, 30, 0, time.UTC),
exp: "2024-01-01",
}, {
title: "Template using tz",
in: `{{ . | tz "Europe/Paris" }}`,
data: time.Date(2024, 1, 1, 8, 15, 30, 0, time.UTC),
exp: "2024-01-01 09:15:30 +0100 CET",
}, {
title: "Template using invalid tz",
in: `{{ . | tz "Invalid/Timezone" }}`,
data: time.Date(2024, 1, 1, 8, 15, 30, 0, time.UTC),
expErr: "template: :1:7: executing \"\" at <tz \"Invalid/Timezone\">: error calling tz: unknown time zone Invalid/Timezone",
}} {
tc := tc
t.Run(tc.title, func(t *testing.T) {
Expand All @@ -515,8 +531,13 @@ func TestTemplateFuncs(t *testing.T) {
go func() {
defer wg.Done()
got, err := tmpl.ExecuteTextString(tc.in, tc.data)
require.NoError(t, err)
require.Equal(t, tc.exp, got)
if tc.expErr == "" {
require.NoError(t, err)
require.Equal(t, tc.exp, got)
} else {
require.EqualError(t, err, tc.expErr)
require.Empty(t, got)
}
}()
}
wg.Wait()
Expand Down

0 comments on commit dc1e1a2

Please sign in to comment.