Skip to content

Commit 807db97

Browse files
moorereasonbep
authored andcommitted
tpl: Refactor time.AsTime location implementation
1 parent 26eeb29 commit 807db97

File tree

2 files changed

+50
-54
lines changed

2 files changed

+50
-54
lines changed

docs/content/en/functions/time.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,32 +13,32 @@ menu:
1313
keywords: [dates,time,location]
1414
signature: ["time INPUT [LOCATION]"]
1515
workson: []
16-
hugoversion:
16+
hugoversion: "v0.77.0"
1717
relatedfuncs: []
1818
deprecated: false
1919
aliases: []
2020
---
2121

22-
`time` converts a timestamp string with an optional timezone into a [`time.Time`](https://godoc.org/time#Time) structure so you can access its fields:
22+
`time` converts a timestamp string with an optional default location into a [`time.Time`](https://godoc.org/time#Time) structure so you can access its fields:
2323

2424
```
2525
{{ time "2016-05-28" }} → "2016-05-28T00:00:00Z"
2626
{{ (time "2016-05-28").YearDay }} → 149
2727
{{ mul 1000 (time "2016-05-28T10:30:00.00+10:00").Unix }} → 1464395400000, or Unix time in milliseconds
2828
```
2929

30-
## Using Timezone
30+
## Using Locations
3131

32-
The optional 2nd parameter [LOCATION] argument is a string that references a timezone that is associated with the specified time value. If the time value has an explicit timezone or offset specified, it will take precedence over an explicit [LOCATION].
32+
The optional `LOCATION` parameter is a string that sets a default location that is associated with the specified time value. If the time value has an explicit timezone or offset specified, it will take precedence over the `LOCATION` parameter.
33+
34+
The list of valid locations may be system dependent, but should include `UTC`, `Local`, or any location in the [IANA Time Zone database](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
3335

3436
```
3537
{{ time "2020-10-20" }} → 2020-10-20 00:00:00 +0000 UTC
3638
{{ time "2020-10-20" "America/Los_Angeles" }} → 2020-10-20 00:00:00 -0700 PDT
3739
{{ time "2020-01-20" "America/Los_Angeles" }} → 2020-01-20 00:00:00 -0800 PST
3840
```
3941

40-
> **Note**: Timezone support via the [LOCATION] parameter is included with Hugo `0.77`.
41-
4242
## Example: Using `time` to get Month Index
4343

4444
The following example takes a UNIX timestamp---set as `utimestamp: "1489276800"` in a content's front matter---converts the timestamp (string) to an integer using the [`int` function][int], and then uses [`printf`][] to convert the `Month` property of `time` into an index.

tpl/time/time.go

Lines changed: 44 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,33 @@ import (
2121
"github.com/spf13/cast"
2222
)
2323

24+
var timeFormats = []string{
25+
_time.RFC3339,
26+
"2006-01-02T15:04:05", // iso8601 without timezone
27+
_time.RFC1123Z,
28+
_time.RFC1123,
29+
_time.RFC822Z,
30+
_time.RFC822,
31+
_time.RFC850,
32+
_time.ANSIC,
33+
_time.UnixDate,
34+
_time.RubyDate,
35+
"2006-01-02 15:04:05.999999999 -0700 MST", // Time.String()
36+
"2006-01-02",
37+
"02 Jan 2006",
38+
"2006-01-02T15:04:05-0700", // RFC3339 without timezone hh:mm colon
39+
"2006-01-02 15:04:05 -07:00",
40+
"2006-01-02 15:04:05 -0700",
41+
"2006-01-02 15:04:05Z07:00", // RFC3339 without T
42+
"2006-01-02 15:04:05Z0700", // RFC3339 without T or timezone hh:mm colon
43+
"2006-01-02 15:04:05",
44+
_time.Kitchen,
45+
_time.Stamp,
46+
_time.StampMilli,
47+
_time.StampMicro,
48+
_time.StampNano,
49+
}
50+
2451
// New returns a new instance of the time-namespaced template functions.
2552
func New() *Namespace {
2653
return &Namespace{}
@@ -32,72 +59,41 @@ type Namespace struct{}
3259
// AsTime converts the textual representation of the datetime string into
3360
// a time.Time interface.
3461
func (ns *Namespace) AsTime(v interface{}, args ...interface{}) (interface{}, error) {
35-
t, err := cast.ToTimeE(v)
36-
if err != nil {
37-
return nil, err
38-
}
39-
4062
if len(args) == 0 {
63+
t, err := cast.ToTimeE(v)
64+
if err != nil {
65+
return nil, err
66+
}
67+
4168
return t, nil
4269
}
4370

44-
// Otherwise, if a location is specified, attempt to parse the time using the location specified.
45-
// Note: In this case, we require the input variable to be a string for proper parsing.
46-
// Note: We can't convert an existing parsed time by using the `Time.In()` as this CONVERTS/MODIFIES
47-
// the resulting time.
48-
49-
switch givenType := v.(type) {
50-
case string:
51-
// Good, we only support strings
52-
break
71+
timeStr, err := cast.ToStringE(v)
72+
if err != nil {
73+
return nil, err
74+
}
5375

54-
default:
55-
return nil, fmt.Errorf("Creating a time instance with location requires a value of type String. Given type: %s", givenType)
76+
locStr, err := cast.ToStringE(args[0])
77+
if err != nil {
78+
return nil, err
5679
}
5780

58-
location, err := _time.LoadLocation(args[0].(string))
81+
loc, err := _time.LoadLocation(locStr)
5982
if err != nil {
6083
return nil, err
6184
}
6285

6386
// Note: Cast currently doesn't support time with non-default locations. For now, just inlining this.
6487
// Reference: https://github.com/spf13/cast/pull/80
6588

66-
fmts := []string{
67-
_time.RFC3339,
68-
"2006-01-02T15:04:05", // iso8601 without timezone
69-
_time.RFC1123Z,
70-
_time.RFC1123,
71-
_time.RFC822Z,
72-
_time.RFC822,
73-
_time.RFC850,
74-
_time.ANSIC,
75-
_time.UnixDate,
76-
_time.RubyDate,
77-
"2006-01-02 15:04:05.999999999 -0700 MST", // Time.String()
78-
"2006-01-02",
79-
"02 Jan 2006",
80-
"2006-01-02T15:04:05-0700", // RFC3339 without timezone hh:mm colon
81-
"2006-01-02 15:04:05 -07:00",
82-
"2006-01-02 15:04:05 -0700",
83-
"2006-01-02 15:04:05Z07:00", // RFC3339 without T
84-
"2006-01-02 15:04:05Z0700", // RFC3339 without T or timezone hh:mm colon
85-
"2006-01-02 15:04:05",
86-
_time.Kitchen,
87-
_time.Stamp,
88-
_time.StampMilli,
89-
_time.StampMicro,
90-
_time.StampNano,
91-
}
92-
93-
for _, dateType := range fmts {
94-
t, err := _time.ParseInLocation(dateType, v.(string), location)
95-
if err == nil {
89+
for _, dateType := range timeFormats {
90+
t, err2 := _time.ParseInLocation(dateType, timeStr, loc)
91+
if err2 == nil {
9692
return t, nil
9793
}
9894
}
9995

100-
return nil, fmt.Errorf("Unable to ParseInLocation using date \"%s\" with timezone \"%s\"", v, location)
96+
return nil, fmt.Errorf("Unable to ParseInLocation using date %q with timezone %q", v, loc)
10197
}
10298

10399
// Format converts the textual representation of the datetime string into

0 commit comments

Comments
 (0)