Skip to content

Commit

Permalink
docs/test: document how to use custom time formats (#172)
Browse files Browse the repository at this point in the history
  • Loading branch information
caarlos0 committed May 15, 2021
1 parent a78d833 commit 6cbd70c
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 2 deletions.
25 changes: 25 additions & 0 deletions README.md
Expand Up @@ -115,6 +115,31 @@ to facilitate the parsing of envs that are not basic types.
Check the example in the [go doc](http://godoc.org/github.com/caarlos0/env)
for more info.

### A note about `TextUnmarshaler` and `time.Time`

Env supports by default anything that implements the `TextUnmarshaler` interface.
That includes things like `time.Time` for example.
The upside is that depending on the format you need, you don't need to change anything.
The downside is that if you do need time in another format, you'll need to create your own type.

Its fairly straightforward:

```go
type MyTime time.Time

func (t *MyTime) UnmarshalText(text []byte) error {
tt, err := time.Parse("2006-01-02", string(text))
*t = MyTime(tt)
return err
}

type Config struct {
SomeTime MyTime `env:"SOME_TIME"`
}
```

And then you can parse `Config` with `env.Parse`.

## Required fields

The `env` tag option `required` (e.g., `env:"tagKey,required"`) can be added
Expand Down
3 changes: 1 addition & 2 deletions env.go
Expand Up @@ -288,8 +288,7 @@ func getOr(key, defaultValue string, defExists bool, envs map[string]string) (va
}

func set(field reflect.Value, sf reflect.StructField, value string, funcMap map[reflect.Type]ParserFunc) error {
tm := asTextUnmarshaler(field)
if tm != nil {
if tm := asTextUnmarshaler(field); tm != nil {
if err := tm.UnmarshalText([]byte(value)); err != nil {
return newParseError(sf, err)
}
Expand Down
23 changes: 23 additions & 0 deletions env_test.go
Expand Up @@ -1248,3 +1248,26 @@ func TestBlankKey(t *testing.T) {
require.Equal(t, "", val.Blank)
require.Equal(t, "", val.BlankWithTag)
}

type MyTime time.Time

func (t *MyTime) UnmarshalText(text []byte) error {
tt, err := time.Parse("2006-01-02", string(text))
*t = MyTime(tt)
return err
}

func TestCustomTimeParser(t *testing.T) {
type config struct {
SomeTime MyTime `env:"SOME_TIME"`
}

os.Setenv("SOME_TIME", "2021-05-06")
defer os.Unsetenv("SOME_TIME")

var cfg config
require.NoError(t, Parse(&cfg))
require.Equal(t, 2021, time.Time(cfg.SomeTime).Year())
require.Equal(t, time.Month(5), time.Time(cfg.SomeTime).Month())
require.Equal(t, 6, time.Time(cfg.SomeTime).Day())
}

0 comments on commit 6cbd70c

Please sign in to comment.