Skip to content

Commit 2ee3592

Browse files
committed
feat: add parse time location hook
1 parent de5deae commit 2ee3592

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed

decode_hooks.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,26 @@ func StringToTimeDurationHookFunc() DecodeHookFunc {
183183
}
184184
}
185185

186+
// StringToTimeLocationHookFunc returns a DecodeHookFunc that converts
187+
// strings to *time.Location.
188+
func StringToTimeLocationHookFunc() DecodeHookFunc {
189+
return func(
190+
f reflect.Type,
191+
t reflect.Type,
192+
data any,
193+
) (any, error) {
194+
if f.Kind() != reflect.String {
195+
return data, nil
196+
}
197+
if t != reflect.TypeOf(time.Local) {
198+
return data, nil
199+
}
200+
d, err := time.LoadLocation(data.(string))
201+
202+
return d, wrapTimeParseLocationError(err)
203+
}
204+
}
205+
186206
// StringToURLHookFunc returns a DecodeHookFunc that converts
187207
// strings to *url.URL.
188208
func StringToURLHookFunc() DecodeHookFunc {

decode_hooks_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,34 @@ func TestStringToTimeDurationHookFunc(t *testing.T) {
318318
}
319319
}
320320

321+
func TestStringToTimeLocationHookFunc(t *testing.T) {
322+
f := StringToTimeLocationHookFunc()
323+
324+
locationValue := reflect.ValueOf(time.Local)
325+
strValue := reflect.ValueOf("")
326+
cases := []struct {
327+
f, t reflect.Value
328+
result any
329+
err bool
330+
}{
331+
{reflect.ValueOf("UTC"), locationValue, time.UTC, false},
332+
{reflect.ValueOf("UTC2"), locationValue, (*time.Location)(nil), true},
333+
{reflect.ValueOf("UTC"), strValue, "UTC", false},
334+
}
335+
336+
for i, tc := range cases {
337+
actual, err := DecodeHookExec(f, tc.f, tc.t)
338+
if tc.err != (err != nil) {
339+
t.Fatalf("case %d: expected err %#v", i, tc.err)
340+
}
341+
if !reflect.DeepEqual(actual, tc.result) {
342+
t.Fatalf(
343+
"case %d: expected %#v, got %#v",
344+
i, tc.result, actual)
345+
}
346+
}
347+
}
348+
321349
func TestStringToURLHookFunc(t *testing.T) {
322350
f := StringToURLHookFunc()
323351

errors.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,3 +230,15 @@ func wrapTimeParseDurationError(err error) error {
230230

231231
return err
232232
}
233+
234+
func wrapTimeParseLocationError(err error) error {
235+
if err == nil {
236+
return nil
237+
}
238+
errMsg := err.Error()
239+
if strings.Contains(errMsg, "unknown time zone") || strings.HasPrefix(errMsg, "time: unknown format") {
240+
return fmt.Errorf("invalid time zone format: %w", err)
241+
}
242+
243+
return err
244+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy