Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Computing time/duration in Golang templates

I have a structure that gets rendered via template. e.g.:

type Foo struct {
  Created time.Time
  ...
}

I pass this value to a template, and I’d like to this rendered see:

  Created at 2022-11-22 9:50 (0d1h12m34s ago)

Displaying the timestamp (and formatting it) is easy enough, but I can’t find a way to calculate the interval.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Created at {{.Created}} ({{???}} ago)

In go, this would be accomplished by time.Since(foo.Created) which returns a Duration, and then I can convert duration to string in various ways.

But doing the calculation in the template itself does not seem possible:

function "time" not defined

Or is it?
Can’t find any information that explicitly tells me that time (or other arbitrary functions) are never ever allowed in templates. So I don’t know if I’m just calling it wrong.

(I know I could create a new FooTemplateValue from a Foo add that field, so the template can render the duration as-is. I was just trying to avoid it if I can and use the actual object as-is).

>Solution :

You can register a custom template function using template.FuncMap, then you can invoke that function inside the template just like you would invoke a builtin function.

template.New("").Funcs(template.FuncMap{
    "dur_until_now": func(t time.Time) time.Duration {
        return time.Now().Sub(t)
    },
}).Parse(`{{ dur_until_now .Created }}`)

https://go.dev/play/p/wM2f1oDFtDr


Or you can declare a custom time type and have that type implement a method that produces the desired value, then you can invoke that method inside the template directly on the field.

type MyTime struct{ time.Time }

func (t MyTime) DurUntilNow() time.Duration {
    return time.Now().Sub(t.Time)
}

// ...
.Parse(`{{ .Created.DurUntilNow }}`)

https://go.dev/play/p/3faW4nTzK3-

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading