-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error parsing time.Time #496
Comments
Is there a workaround for this? |
@ethanmick my workaround now is to define the field as string and then parse it into date "manually" |
Bumped into this, things have moved on: The unmarshal method signature isn't quite as presently decribed in the docs (it is viper.Unmarshal(rawVal interface{}, opts ...DecoderConfigOption) error) so with options config glued together with something like (fiddled to handle empty strings below) mapstructure.StringToTimeHookFunc you can configure the decode and get what you want. err := viper.GetViper().Unmarshal(&config, func(m *mapstructure.DecoderConfig) {
m.DecodeHook = mapstructure.ComposeDecodeHookFunc(
func(
f reflect.Type,
t reflect.Type,
data interface{}) (interface{}, error) {
if f.Kind() != reflect.String {
return data, nil
}
if t != reflect.TypeOf(time.Time{}) {
return data, nil
}
asString := data.(string)
if asString == "" {
return time.Time{}, nil
}
// Convert it by parsing
return time.Parse("2006-01-02", asString)
},
mapstructure.StringToTimeDurationHookFunc(),
mapstructure.StringToSliceHookFunc(","),
)
})
if err != nil {
log.Fatal().Err(err).Msg("Failed to unmarshal config")
} |
Thanks @lachlanmunro. FYI a more comprehensive time decoder function is given here: mitchellh/mapstructure#159 (comment) |
I guess this can be closed then |
Just in case someone has a quick answer before I dive into the code, why does Even though |
Parsing time.Duration is obvious, while parsing time.Time also needs a(t least a) format. |
A simpler work-around for certain cases may be this: timeVal := viper.GetTime("time_val")
viper.Set("time_val", timeVal)
viper.Unmarshal(&structVal) This pre-converts it to a time value and you'll get all of viper's built-in time format detection. It might be a pain to do on a complicated configuration file, but for something simple, this does the trick for me. |
go: 1.10
viper: 1.0.2
when a field to be parsed is
time.Time
viper fails with errorexpected a map, got 'string'
Test to reproduce (can be added in
viper_test.go
)result:
The text was updated successfully, but these errors were encountered: