diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..73f69e0
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/.idea/dateparse_tag.iml b/.idea/dateparse_tag.iml
new file mode 100644
index 0000000..5e764c4
--- /dev/null
+++ b/.idea/dateparse_tag.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..019aa83
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..911ef2d
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/watcherTasks.xml b/.idea/watcherTasks.xml
new file mode 100644
index 0000000..4aabca4
--- /dev/null
+++ b/.idea/watcherTasks.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index e2ea51f..808b776 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,39 @@
# dateparse_tag
dateparse time by struct tag
+
+## 简介
+WithTagName() // 自定义你想要使用的tag名称,默认为dateFormat
+WithDefaultTagValue() // 定义这个tag的默认值,默认为 default
+WithDefaultFormat() // 定义时间格式化样式,默认为 2006-01-02 15:04:05
+WithEmptyValue() // 定义一个空值返回,当指定结构体的指定字段为空值时,返回你想要的空值,默认为 `""`
+
+## install&安装
+```go
+ go get github.com/cowardmrx/dateparse_tag
+```
+## use&使用
+```go
+type User struct {
+ Name string `json:"name"`
+ BirthDay string `json:"birth_day" format_date:"default"`
+}
+
+func TestNewDateParseTag(t *testing.T) {
+ u := new(User)
+
+ u.Name = "张三"
+ u.BirthDay = time.Now().String()
+
+ t.Logf("user : %v", u)
+
+ dp := NewDateParseTag(WithTagName("format_date"))
+
+ dp.Parse(u, u)
+
+ t.Logf("user new %v", u)
+}
+
+// old user : &{张三 2022-01-12 14:10:17.1867047 +0800 CST m=+0.003444301}
+// new user &{张三 2022-01-12 14:10:17}
+
+```
\ No newline at end of file
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..5826062
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,5 @@
+module github.com/cowardmrx/dateparse_tag
+
+go 1.17
+
+require github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de // indirect
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..6436794
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,11 @@
+github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de h1:FxWPpzIjnTlhPwqqXc4/vE0f7GvRjuAsbW+HOIe8KnA=
+github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de/go.mod h1:DCaWoUhZrYW9p1lxo/cm8EmUOOzAPSEZNGF2DK1dJgw=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/parse.go b/parse.go
new file mode 100644
index 0000000..a79c2d0
--- /dev/null
+++ b/parse.go
@@ -0,0 +1,161 @@
+package dateparse_tag
+
+import (
+ "fmt"
+ "reflect"
+)
+
+const (
+ DefaultFormatLayout = "2006-01-02 15:04:05"
+ DefaultTagName = "dateFormat"
+ DefaultTagValue = "default"
+)
+
+type dateParseTag struct {
+ TagName string // Define the tag you want , default tag is `dateFormat`
+ DefaultTagValue string // define the tag default value you want , default tag value `default`
+ DefaultFormatLayout string // date format default layout
+ EmptyValue string // Return when the value is null
+}
+
+type Options func(dp *dateParseTag)
+
+func WithTagName(tagName string) Options {
+ return func(dp *dateParseTag) {
+
+ if tagName == "" || len(tagName) <= 0 {
+ dp.TagName = "dateFormat"
+ } else {
+ dp.TagName = tagName
+ }
+
+ }
+}
+
+func WithDefaultTagValue(tagVal string) Options {
+ return func(dp *dateParseTag) {
+ if tagVal == "" || len(tagVal) <= 0 {
+ dp.DefaultTagValue = "default"
+ } else {
+ dp.DefaultTagValue = tagVal
+ }
+ }
+}
+
+func WithDefaultFormat(defaultFormatLayout string) Options {
+ return func(dp *dateParseTag) {
+ if defaultFormatLayout == "" || len(defaultFormatLayout) <= 0 {
+ dp.DefaultFormatLayout = DefaultFormatLayout
+ } else {
+ dp.DefaultFormatLayout = defaultFormatLayout
+ }
+ }
+}
+
+func WithEmptyValue(emptyValue string) Options {
+ return func(dp *dateParseTag) {
+ dp.EmptyValue = emptyValue
+ }
+}
+
+type DateParseTag interface {
+ Parse(in, out interface{})
+}
+
+func NewDateParseTag(opts ...Options) DateParseTag {
+ dp := new(dateParseTag)
+
+ for _, v := range opts {
+ v(dp)
+ }
+
+ dp = dp.check()
+
+ return dp
+}
+
+func (dp *dateParseTag) check() *dateParseTag {
+ if dp.TagName == "" || len(dp.TagName) <= 0 {
+ dp.TagName = DefaultTagName
+ }
+
+ if dp.DefaultFormatLayout == "" || len(dp.DefaultFormatLayout) <= 0 {
+ dp.DefaultFormatLayout = DefaultFormatLayout
+ }
+
+ if dp.EmptyValue == "" || len(dp.EmptyValue) <= 0 {
+ dp.EmptyValue = ""
+ }
+
+ return dp
+}
+
+// @method Parse
+// @description: parse time
+// @receiver dp
+// @param in interface{}
+// @param out interface{}
+func (dp *dateParseTag) Parse(in, out interface{}) {
+ tType := reflect.TypeOf(in).Elem()
+
+ tValue := reflect.ValueOf(in).Elem()
+
+ for i := 0; i < tType.NumField(); i++ {
+ field := tType.Field(i)
+
+ tag, ok := field.Tag.Lookup(dp.TagName)
+
+ if !ok {
+ continue
+ }
+
+ fieldVal := tValue.FieldByName(field.Name)
+
+ if fieldVal.String() == "" || len(fieldVal.String()) <= 0 {
+
+ // 校验是否为该空值返回是否为时间类型格式
+ tFormat, err := validateDateFormat(dp.EmptyValue)
+
+ // 如果不是时间类型格式那么直接返回emptyValue的值 反之按照layout格式化返回
+ if err != nil {
+ fieldVal.SetString(dp.EmptyValue)
+ } else {
+ fieldVal.SetString(parseTime(dp.dateFormatLayout(tFormat), dp.EmptyValue))
+ }
+
+ } else {
+
+ fieldVal.SetString(parseTime(dp.dateFormatLayout(tag), fieldVal.String()))
+ }
+
+ }
+
+ out = in
+ return
+}
+
+// @method dateFormatLayout
+// @description: get date format layout
+// @receiver dp
+// @param tag string
+// @return string
+func (dp *dateParseTag) dateFormatLayout(tag string) string {
+ if tag == dp.DefaultTagValue {
+ tag = dp.DefaultFormatLayout
+ } else {
+
+ if tag == DefaultTagValue {
+ tag = DefaultFormatLayout
+ }
+
+ tFormat, err := validateDateFormat(tag)
+
+ if err != nil {
+ panic(fmt.Sprintf("tag value can't parse: %v", tag))
+ }
+
+ tag = tFormat
+ }
+
+ return tag
+}
diff --git a/parse_test.go b/parse_test.go
new file mode 100644
index 0000000..a253eba
--- /dev/null
+++ b/parse_test.go
@@ -0,0 +1,26 @@
+package dateparse_tag
+
+import (
+ "testing"
+ "time"
+)
+
+type User struct {
+ Name string `json:"name"`
+ BirthDay string `json:"birth_day" format_date:"default"`
+}
+
+func TestNewDateParseTag(t *testing.T) {
+ u := new(User)
+
+ u.Name = "张三"
+ u.BirthDay = time.Now().String()
+
+ t.Logf("old user : %v", u)
+
+ dp := NewDateParseTag(WithTagName("format_date"))
+
+ dp.Parse(u, u)
+
+ t.Logf("new user %v", u)
+}
diff --git a/tool.go b/tool.go
new file mode 100644
index 0000000..13cdd28
--- /dev/null
+++ b/tool.go
@@ -0,0 +1,36 @@
+package dateparse_tag
+
+import (
+ "fmt"
+ "github.com/araddon/dateparse"
+)
+
+// @method validateDateFormat
+// @description: validate date layout
+// @param layout string
+// @return string
+// @return error
+func validateDateFormat(layout string) (string, error) {
+ tFormat, err := dateparse.ParseFormat(layout)
+
+ if err != nil {
+ return "", err
+ }
+
+ return tFormat, nil
+}
+
+// @method parseTime
+// @description: parse time
+// @param layout string
+// @param times string
+// @return string
+func parseTime(layout, times string) string {
+ t1, err := dateparse.ParseLocal(times)
+
+ if err != nil {
+ panic(fmt.Sprintf("time parse failed: %v : %v", times, err.Error()))
+ }
+
+ return t1.Format(layout)
+}