diff --git a/docs/custom-api.md b/docs/custom-api.md index d42d1fc..3a37df2 100644 --- a/docs/custom-api.md +++ b/docs/custom-api.md @@ -378,6 +378,7 @@ The following helper functions provided by Glance are available: - `offsetNow(offset string) time.Time`: Returns the current time with an offset. The offset can be positive or negative and must be in the format "3h" "-1h" or "2h30m10s". - `duration(str string) time.Duration`: Parses a string such as `1h`, `24h`, `5h30m`, etc into a `time.Duration`. - `parseTime(layout string, s string) time.Time`: Parses a string into time.Time. The layout must be provided in Go's [date format](https://pkg.go.dev/time#pkg-constants). You can alternatively use these values instead of the literal format: "unix", "RFC3339", "RFC3339Nano", "DateTime", "DateOnly". +- `parseLocalTime(layout string, s string) time.Time`: Same as the above, except in the absence of a timezone, it will use the local timezone instead of UTC. - `parseRelativeTime(layout string, s string) time.Time`: A shorthand for `{{ .String "date" | parseTime "rfc3339" | toRelativeTime }}`. - `add(a, b float) float`: Adds two numbers. - `sub(a, b float) float`: Subtracts two numbers. diff --git a/internal/glance/widget-custom-api.go b/internal/glance/widget-custom-api.go index 93d51c0..d5a1b67 100644 --- a/internal/glance/widget-custom-api.go +++ b/internal/glance/widget-custom-api.go @@ -450,11 +450,16 @@ var customAPITemplateFuncs = func() template.FuncMap { return d }, - "parseTime": customAPIFuncParseTime, + "parseTime": func(layout, value string) time.Time { + return customAPIFuncParseTimeInLocation(layout, value, time.UTC) + }, + "parseLocalTime": func(layout, value string) time.Time { + return customAPIFuncParseTimeInLocation(layout, value, time.Local) + }, "toRelativeTime": dynamicRelativeTimeAttrs, "parseRelativeTime": func(layout, value string) template.HTMLAttr { // Shorthand to do both of the above with a single function call - return dynamicRelativeTimeAttrs(customAPIFuncParseTime(layout, value)) + return dynamicRelativeTimeAttrs(customAPIFuncParseTimeInLocation(layout, value, time.UTC)) }, // The reason we flip the parameter order is so that you can chain multiple calls together like this: // {{ .JSON.String "foo" | trimPrefix "bar" | doSomethingElse }} @@ -528,8 +533,8 @@ var customAPITemplateFuncs = func() template.FuncMap { }, "sortByTime": func(key, layout, order string, results []decoratedGJSONResult) []decoratedGJSONResult { sort.Slice(results, func(a, b int) bool { - timeA := customAPIFuncParseTime(layout, results[a].String(key)) - timeB := customAPIFuncParseTime(layout, results[b].String(key)) + timeA := customAPIFuncParseTimeInLocation(layout, results[a].String(key), time.UTC) + timeB := customAPIFuncParseTimeInLocation(layout, results[b].String(key), time.UTC) if order == "asc" { return timeA.Before(timeB) @@ -566,7 +571,7 @@ var customAPITemplateFuncs = func() template.FuncMap { return funcs }() -func customAPIFuncParseTime(layout, value string) time.Time { +func customAPIFuncParseTimeInLocation(layout, value string, loc *time.Location) time.Time { switch strings.ToLower(layout) { case "unix": asInt, err := strconv.ParseInt(value, 10, 64) @@ -585,7 +590,7 @@ func customAPIFuncParseTime(layout, value string) time.Time { layout = time.DateOnly } - parsed, err := time.Parse(layout, value) + parsed, err := time.ParseInLocation(layout, value, loc) if err != nil { return time.Unix(0, 0) }