Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions date.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,27 @@ func toDate(fmt, str string) time.Time {
return t
}

func toDateInZone(fmt, str string, timezone string) time.Time {
z, err := time.LoadLocation(timezone)
if err != nil {
z, _ = time.LoadLocation("UTC")
}
t, _ := time.ParseInLocation(fmt, str, z)
return t
}

func mustToDate(fmt, str string) (time.Time, error) {
return time.ParseInLocation(fmt, str, time.Local)
}

func mustToDateInZone(fmt, str string, timezone string) (time.Time, error) {
z, err := time.LoadLocation(timezone)
if err != nil {
return time.Time{}, err
}
return time.ParseInLocation(fmt, str, z)
}

func unixEpoch(date time.Time) string {
return strconv.FormatInt(date.Unix(), 10)
}
35 changes: 35 additions & 0 deletions date_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,41 @@ func TestDateInZone(t *testing.T) {
}
}

func TestToDateInZone(t *testing.T) {
tpl := `{{ date_in_zone "02 Jan 06 15:04 MST" (toDateInZone "2006-01-02 15:04" "2025-10-20 19:30" "Europe/Paris") "UTC" }}`
if err := runt(tpl, "20 Oct 25 17:30 UTC"); err != nil {
t.Error(err)
}

tpl = `{{ date_in_zone "02 Jan 06 15:04 MST" (toDateInZone "2006-01-02 15:04" "2025-11-20 19:30" "Europe/Paris") "UTC" }}`
if err := runt(tpl, "20 Nov 25 18:30 UTC"); err != nil {
t.Error(err)
}

tpl = `{{ date_in_zone "02 Jan 06 15:04 MST" (toDateInZone "2006-01-02 15:04" "2025-10-20 19:30" "Europe/Paris") "Europe/London" }}`
if err := runt(tpl, "20 Oct 25 18:30 BST"); err != nil {
t.Error(err)
}

// Test case of invalid timezone
tpl = `{{ date_in_zone "02 Jan 06 15:04 MST" (toDateInZone "2006-01-02 15:04" "2025-11-20 19:30" "Europe/Paris") "foobar" }}`
if err := runt(tpl, "20 Nov 25 18:30 UTC"); err != nil {
t.Error(err)
}
}

func TestMustToDateInZone(t *testing.T) {
tpl := `{{ date_in_zone "02 Jan 06 15:04 MST" (mustToDateInZone "2006-01-02 15:04" "2025-10-20 19:30" "Europe/Paris") "UTC" }}`
if err := runt(tpl, "20 Oct 25 17:30 UTC"); err != nil {
t.Error(err)
}

tpl = `{{ date_in_zone "02 Jan 06 15:04 MST" (mustToDateInZone "2006-01-02 15:04" "2025-11-20 19:30" "Europe/Paris") "UTC" }}`
if err := runt(tpl, "20 Nov 25 18:30 UTC"); err != nil {
t.Error(err)
}
}

func TestDuration(t *testing.T) {
tpl := "{{ duration .Secs }}"
if err := runtv(tpl, "1m1s", map[string]interface{}{"Secs": "61"}); err != nil {
Expand Down
15 changes: 15 additions & 0 deletions docs/date.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,18 @@ This is useful when you want to convert a string date to another format
```
toDate "2006-01-02" "2017-12-31" | date "02/01/2006"
```

## toDateInZone, mustToDateInZone

`toDateInZone` converts a string to a date in the given timezone. The first
argument is the date layout, the second the date string and the third the timezone.
If the string can't be converted it returns the zero value, if the timezone can't be
converted it returns the date in UTC.
`mustToDateInZone` will return an error in case the string or timezone cannot be converted.

The example below converts "2025-10-20 19:30" in "CET" to "20 Oct 25 17:30 UTC".

```
dateInZone "02 Jan 06 15:04 MST" (toDateInZone "2006-01-02 15:04" "2025-10-20 19:30" "Europe/Paris") "UTC" }}
```

2 changes: 2 additions & 0 deletions functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,10 @@ var genericMap = map[string]interface{}{
"must_date_modify": mustDateModify,
"mustDateModify": mustDateModify,
"mustToDate": mustToDate,
"mustToDateInZone": mustToDateInZone,
"now": time.Now,
"toDate": toDate,
"toDateInZone": toDateInZone,
"unixEpoch": unixEpoch,

// Strings
Expand Down