11
11
// See the License for the specific language governing permissions and
12
12
// limitations under the License.
13
13
14
- package time
14
+ package time_test
15
15
16
16
import (
17
17
"strings"
18
18
"testing"
19
- "time"
19
+ gtime "time"
20
20
21
21
qt "github.com/frankban/quicktest"
22
22
23
23
"github.com/gohugoio/hugo/common/htime"
24
+ "github.com/gohugoio/hugo/hugolib"
25
+ "github.com/gohugoio/hugo/tpl/time"
26
+
24
27
translators "github.com/gohugoio/localescompressed"
25
28
)
26
29
27
30
func TestTimeLocation (t * testing.T ) {
28
31
t .Parallel ()
29
32
30
- loc , _ := time .LoadLocation ("America/Antigua" )
31
- ns := New (htime .NewTimeFormatter (translators .GetTranslator ("en" )), loc )
33
+ b := hugolib .NewIntegrationTestBuilder (
34
+ hugolib.IntegrationTestConfig {T : t },
35
+ ).Build ()
36
+
37
+ loc , _ := gtime .LoadLocation ("America/Antigua" )
38
+ ns := time .New (htime .NewTimeFormatter (translators .GetTranslator ("en" )), loc , b .H .Deps )
32
39
33
40
for i , test := range []struct {
34
41
name string
@@ -72,7 +79,7 @@ func TestTimeLocation(t *testing.T) {
72
79
// See https://github.com/gohugoio/hugo/issues/8843#issuecomment-891551447
73
80
// Drop the location string (last element) when comparing,
74
81
// as that may change depending on the local locale.
75
- timeStr := result .(time .Time ).String ()
82
+ timeStr := result .(gtime .Time ).String ()
76
83
timeStr = timeStr [:strings .LastIndex (timeStr , " " )]
77
84
if ! strings .HasPrefix (test .expect .(string ), timeStr ) {
78
85
t .Errorf ("[%d] AsTime got %v but expected %v" , i , timeStr , test .expect )
@@ -85,25 +92,30 @@ func TestTimeLocation(t *testing.T) {
85
92
func TestFormat (t * testing.T ) {
86
93
c := qt .New (t )
87
94
95
+ b := hugolib .NewIntegrationTestBuilder (
96
+ hugolib.IntegrationTestConfig {T : t },
97
+ ).Build ()
98
+
88
99
c .Run ("UTC" , func (c * qt.C ) {
89
100
c .Parallel ()
90
- ns := New (htime .NewTimeFormatter (translators .GetTranslator ("en" )), time .UTC )
101
+
102
+ ns := time .New (htime .NewTimeFormatter (translators .GetTranslator ("en" )), gtime .UTC , b .H .Deps )
91
103
92
104
for i , test := range []struct {
93
105
layout string
94
106
value any
95
107
expect any
96
108
}{
97
109
{"Monday, Jan 2, 2006" , "2015-01-21" , "Wednesday, Jan 21, 2015" },
98
- {"Monday, Jan 2, 2006" , time .Date (2015 , time .January , 21 , 0 , 0 , 0 , 0 , time .UTC ), "Wednesday, Jan 21, 2015" },
110
+ {"Monday, Jan 2, 2006" , gtime .Date (2015 , gtime .January , 21 , 0 , 0 , 0 , 0 , gtime .UTC ), "Wednesday, Jan 21, 2015" },
99
111
{"This isn't a date layout string" , "2015-01-21" , "This isn't a date layout string" },
100
112
// The following test case gives either "Tuesday, Jan 20, 2015" or "Monday, Jan 19, 2015" depending on the local time zone
101
- {"Monday, Jan 2, 2006" , 1421733600 , time .Unix (1421733600 , 0 ).Format ("Monday, Jan 2, 2006" )},
113
+ {"Monday, Jan 2, 2006" , 1421733600 , gtime .Unix (1421733600 , 0 ).Format ("Monday, Jan 2, 2006" )},
102
114
{"Monday, Jan 2, 2006" , 1421733600.123 , false },
103
- {time .RFC3339 , time .Date (2016 , time .March , 3 , 4 , 5 , 0 , 0 , time .UTC ), "2016-03-03T04:05:00Z" },
104
- {time .RFC1123 , time .Date (2016 , time .March , 3 , 4 , 5 , 0 , 0 , time .UTC ), "Thu, 03 Mar 2016 04:05:00 UTC" },
105
- {time .RFC3339 , "Thu, 03 Mar 2016 04:05:00 UTC" , "2016-03-03T04:05:00Z" },
106
- {time .RFC1123 , "2016-03-03T04:05:00Z" , "Thu, 03 Mar 2016 04:05:00 UTC" },
115
+ {gtime .RFC3339 , gtime .Date (2016 , gtime .March , 3 , 4 , 5 , 0 , 0 , gtime .UTC ), "2016-03-03T04:05:00Z" },
116
+ {gtime .RFC1123 , gtime .Date (2016 , gtime .March , 3 , 4 , 5 , 0 , 0 , gtime .UTC ), "Thu, 03 Mar 2016 04:05:00 UTC" },
117
+ {gtime .RFC3339 , "Thu, 03 Mar 2016 04:05:00 UTC" , "2016-03-03T04:05:00Z" },
118
+ {gtime .RFC1123 , "2016-03-03T04:05:00Z" , "Thu, 03 Mar 2016 04:05:00 UTC" },
107
119
// Custom layouts, as introduced in Hugo 0.87.
108
120
{":date_medium" , "2015-01-21" , "Jan 21, 2015" },
109
121
} {
@@ -128,9 +140,9 @@ func TestFormat(t *testing.T) {
128
140
c .Run ("TZ America/Los_Angeles" , func (c * qt.C ) {
129
141
c .Parallel ()
130
142
131
- loc , err := time .LoadLocation ("America/Los_Angeles" )
143
+ loc , err := gtime .LoadLocation ("America/Los_Angeles" )
132
144
c .Assert (err , qt .IsNil )
133
- ns := New (htime .NewTimeFormatter (translators .GetTranslator ("en" )), loc )
145
+ ns := time . New (htime .NewTimeFormatter (translators .GetTranslator ("en" )), loc , b . H . Deps )
134
146
135
147
d , err := ns .Format (":time_full" , "2020-03-09T11:00:00" )
136
148
@@ -142,28 +154,32 @@ func TestFormat(t *testing.T) {
142
154
func TestDuration (t * testing.T ) {
143
155
t .Parallel ()
144
156
145
- ns := New (htime .NewTimeFormatter (translators .GetTranslator ("en" )), time .UTC )
157
+ b := hugolib .NewIntegrationTestBuilder (
158
+ hugolib.IntegrationTestConfig {T : t },
159
+ ).Build ()
160
+
161
+ ns := time .New (htime .NewTimeFormatter (translators .GetTranslator ("en" )), gtime .UTC , b .H .Deps )
146
162
147
163
for i , test := range []struct {
148
164
unit any
149
165
num any
150
166
expect any
151
167
}{
152
- {"nanosecond" , 10 , 10 * time .Nanosecond },
153
- {"ns" , 10 , 10 * time .Nanosecond },
154
- {"microsecond" , 20 , 20 * time .Microsecond },
155
- {"us" , 20 , 20 * time .Microsecond },
156
- {"µs" , 20 , 20 * time .Microsecond },
157
- {"millisecond" , 20 , 20 * time .Millisecond },
158
- {"ms" , 20 , 20 * time .Millisecond },
159
- {"second" , 30 , 30 * time .Second },
160
- {"s" , 30 , 30 * time .Second },
161
- {"minute" , 20 , 20 * time .Minute },
162
- {"m" , 20 , 20 * time .Minute },
163
- {"hour" , 20 , 20 * time .Hour },
164
- {"h" , 20 , 20 * time .Hour },
168
+ {"nanosecond" , 10 , 10 * gtime .Nanosecond },
169
+ {"ns" , 10 , 10 * gtime .Nanosecond },
170
+ {"microsecond" , 20 , 20 * gtime .Microsecond },
171
+ {"us" , 20 , 20 * gtime .Microsecond },
172
+ {"µs" , 20 , 20 * gtime .Microsecond },
173
+ {"millisecond" , 20 , 20 * gtime .Millisecond },
174
+ {"ms" , 20 , 20 * gtime .Millisecond },
175
+ {"second" , 30 , 30 * gtime .Second },
176
+ {"s" , 30 , 30 * gtime .Second },
177
+ {"minute" , 20 , 20 * gtime .Minute },
178
+ {"m" , 20 , 20 * gtime .Minute },
179
+ {"hour" , 20 , 20 * gtime .Hour },
180
+ {"h" , 20 , 20 * gtime .Hour },
165
181
{"hours" , 20 , false },
166
- {"hour" , "30" , 30 * time .Hour },
182
+ {"hour" , "30" , 30 * gtime .Hour },
167
183
} {
168
184
result , err := ns .Duration (test .unit , test .num )
169
185
if b , ok := test .expect .(bool ); ok && ! b {
@@ -181,3 +197,74 @@ func TestDuration(t *testing.T) {
181
197
}
182
198
}
183
199
}
200
+
201
+ func TestIn (t * testing.T ) {
202
+ t .Parallel ()
203
+
204
+ b := hugolib .NewIntegrationTestBuilder (
205
+ hugolib.IntegrationTestConfig {T : t },
206
+ ).Build ()
207
+
208
+ ns := time .New (htime .NewTimeFormatter (translators .GetTranslator ("en" )), gtime .UTC , b .H .Deps )
209
+
210
+ in := gtime .Date (2025 , gtime .March , 31 , 15 , 0 , 0 , 0 , gtime .UTC )
211
+
212
+ tests := []struct {
213
+ name string
214
+ tzn string // time zone name
215
+ want string
216
+ wantErr bool
217
+ }{
218
+ {name : "A" , tzn : "America/Denver" , want : "2025-03-31T09:00:00-06:00" , wantErr : false },
219
+ {name : "B" , tzn : "Australia/Adelaide" , want : "2025-04-01T01:30:00+10:30" , wantErr : false },
220
+ {name : "C" , tzn : "Europe/Oslo" , want : "2025-03-31T17:00:00+02:00" , wantErr : false },
221
+ {name : "D" , tzn : "UTC" , want : "2025-03-31T15:00:00+00:00" , wantErr : false },
222
+ {name : "E" , tzn : "" , want : "2025-03-31T15:00:00+00:00" , wantErr : false },
223
+ {name : "F" , tzn : "InvalidTimeZoneName" , want : "0001-01-01T00:00:00+00:00" , wantErr : true },
224
+ }
225
+
226
+ for _ , tt := range tests {
227
+ t .Run (tt .name , func (t * testing.T ) {
228
+ result , err := ns .In (tt .tzn , in )
229
+ if (err != nil ) != tt .wantErr {
230
+ t .Errorf ("time.In() error = %v, wantErr %v" , err , tt .wantErr )
231
+ return
232
+ }
233
+ got := result .Format ("2006-01-02T15:04:05-07:00" )
234
+ if got != tt .want {
235
+ t .Errorf ("time.In() = %v, want %v" , got , tt .want )
236
+ }
237
+ })
238
+ }
239
+ }
240
+
241
+ // For benchmark tests below.
242
+ var timeZoneNames []string = []string {"America/New_York" , "Europe/Oslo" , "Australia/Sydney" , "UTC" , "Local" }
243
+
244
+ func BenchmarkInWithCaching (b * testing.B ) {
245
+ bb := hugolib .NewIntegrationTestBuilder (
246
+ hugolib.IntegrationTestConfig {T : b },
247
+ ).Build ()
248
+
249
+ ns := time .New (htime .NewTimeFormatter (translators .GetTranslator ("en" )), gtime .UTC , bb .H .Deps )
250
+
251
+ for i := 0 ; i < b .N ; i ++ {
252
+ timeZoneName := timeZoneNames [i % len (timeZoneNames )]
253
+ _ , err := ns .In (timeZoneName , gtime .Now ())
254
+ if err != nil {
255
+ b .Fatalf ("Error during benchmark: %v" , err )
256
+ }
257
+ }
258
+ }
259
+
260
+ func BenchmarkInWithoutCaching (b * testing.B ) {
261
+ for i := 0 ; i < b .N ; i ++ {
262
+ timeZoneName := timeZoneNames [i % len (timeZoneNames )]
263
+ location , err := gtime .LoadLocation (timeZoneName )
264
+ if err != nil {
265
+ b .Fatalf ("Error during benchmark: %v" , err )
266
+ }
267
+
268
+ _ = gtime .Now ().In (location )
269
+ }
270
+ }
0 commit comments