gotimebindglide-golanggo-echo

How do I bind a date string to a struct?


type TestModel struct {
  Date     time.Time `json:"date" form:"date" gorm:"index"`
  gorm.Model
}

i'm using echo framwork, and I have a struct like the one above, and I get string data like '2021-09-27' , how can I bind it to the struct?

func CreateDiary(c echo.Context) error {
    var getData model.TestModel
    if err := (&echo.DefaultBinder{}).BindBody(c, &getData); err != nil {
        fmt.Print(err.Error())
    }
   return c.JSON(200, getData)
}

When I code like this, I get the following error:

code=400, message=parsing time "2021-09-27" as "2006-01-02T15:04:05Z07:00": cannot parse "" as "T", internal=parsing time "2021-09-27" as "2006-01-02T15:04:05Z07:00": cannot parse "" as "T"

I'm a golang beginner, can you show me a simple example??, please.

i'm using echo framwork


Solution

  • Here is list of available tags used in echo. If you want to parse from body, then use json

    You need to wrap time.Time into custom struct and then implement json.Marshaler and json.Unmarshaler interfaces

    Example

    package main
    
    import (
        "fmt"
        "strings"
        "time"
    
        "github.com/labstack/echo/v4"
    )
    
    type CustomTime struct {
        time.Time
    }
    
    type TestModel struct {
        Date CustomTime `json:"date"`
    }
    
    func (t CustomTime) MarshalJSON() ([]byte, error) {
        date := t.Time.Format("2006-01-02")
        date = fmt.Sprintf(`"%s"`, date)
        return []byte(date), nil
    }
    
    func (t *CustomTime) UnmarshalJSON(b []byte) (err error) {
        s := strings.Trim(string(b), "\"")
    
        date, err := time.Parse("2006-01-02", s)
        if err != nil {
            return err
        }
        t.Time = date
        return
    }
    
    func main() {
        e := echo.New()
        e.POST("/test", CreateDiary)
        e.Logger.Fatal(e.Start(":1323"))
    }
    
    func CreateDiary(c echo.Context) error {
        var getData TestModel
        if err := (&echo.DefaultBinder{}).BindBody(c, &getData); err != nil {
            fmt.Print(err.Error())
        }
        return c.JSON(200, getData)
    }
    

    test

    curl -X POST http://localhost:1323/test -H 'Content-Type: application/json' -d '{"date":"2021-09-27"}'