summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2022-06-06 09:48:40 +0200
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2022-06-07 13:02:58 +0200
commit0566bbf7c7f2898fcd1d6156b27733cd48aa0449 (patch)
tree69ee0bde4d334cb0565afd5fb4e17247c946aad9 /common
parent534e7155bb504682a37f5663d8c913e439b11e07 (diff)
Fix raw TOML dates in where/eq
Note that this has only been a problem with "raw dates" in TOML files in /data and similar. The predefined front matter dates `.Date` etc. are converted to a Go Time and has worked fine even after upgrading to v2 of the go-toml lib. Fixes #9979
Diffstat (limited to 'common')
-rw-r--r--common/hreflect/helpers.go40
-rw-r--r--common/htime/time.go12
2 files changed, 47 insertions, 5 deletions
diff --git a/common/hreflect/helpers.go b/common/hreflect/helpers.go
index e1c01456d..1b7e5acf7 100644
--- a/common/hreflect/helpers.go
+++ b/common/hreflect/helpers.go
@@ -20,7 +20,9 @@ import (
"context"
"reflect"
"sync"
+ "time"
+ "github.com/gohugoio/hugo/common/htime"
"github.com/gohugoio/hugo/common/types"
)
@@ -168,6 +170,44 @@ func GetMethodIndexByName(tp reflect.Type, name string) int {
return m.Index
}
+var (
+ timeType = reflect.TypeOf((*time.Time)(nil)).Elem()
+ asTimeProviderType = reflect.TypeOf((*htime.AsTimeProvider)(nil)).Elem()
+)
+
+// IsTime returns whether tp is a time.Time type or if it can be converted into one
+// in ToTime.
+func IsTime(tp reflect.Type) bool {
+ if tp == timeType {
+ return true
+ }
+
+ if tp.Implements(asTimeProviderType) {
+ return true
+ }
+ return false
+}
+
+// AsTime returns v as a time.Time if possible.
+// The given location is only used if the value implements AsTimeProvider (e.g. go-toml local).
+// A zero Time and false is returned if this isn't possible.
+// Note that this function does not accept string dates.
+func AsTime(v reflect.Value, loc *time.Location) (time.Time, bool) {
+ if v.Kind() == reflect.Interface {
+ return AsTime(v.Elem(), loc)
+ }
+
+ if v.Type() == timeType {
+ return v.Interface().(time.Time), true
+ }
+
+ if v.Type().Implements(asTimeProviderType) {
+ return v.Interface().(htime.AsTimeProvider).AsTime(loc), true
+ }
+
+ return time.Time{}, false
+}
+
// Based on: https://github.com/golang/go/blob/178a2c42254166cffed1b25fb1d3c7a5727cada6/src/text/template/exec.go#L931
func indirectInterface(v reflect.Value) reflect.Value {
if v.Kind() != reflect.Interface {
diff --git a/common/htime/time.go b/common/htime/time.go
index 052a45ed1..d30ecf7e1 100644
--- a/common/htime/time.go
+++ b/common/htime/time.go
@@ -20,8 +20,6 @@ import (
"github.com/bep/clock"
"github.com/spf13/cast"
- toml "github.com/pelletier/go-toml/v2"
-
"github.com/gohugoio/locales"
)
@@ -139,13 +137,12 @@ func (f TimeFormatter) Format(t time.Time, layout string) string {
func ToTimeInDefaultLocationE(i any, location *time.Location) (tim time.Time, err error) {
switch vv := i.(type) {
- case toml.LocalDate:
- return vv.AsTime(location), nil
- case toml.LocalDateTime:
+ case AsTimeProvider:
return vv.AsTime(location), nil
// issue #8895
// datetimes parsed by `go-toml` have empty zone name
// convert back them into string and use `cast`
+ // TODO(bep) add tests, make sure we really need this.
case time.Time:
i = vv.Format(time.RFC3339)
}
@@ -161,3 +158,8 @@ func Now() time.Time {
func Since(t time.Time) time.Duration {
return Clock.Since(t)
}
+
+// AsTimeProvider is implemented by go-toml's LocalDate and LocalDateTime.
+type AsTimeProvider interface {
+ AsTime(zone *time.Location) time.Time
+}