How do I bind a date string to a struct?

Viewed 1520
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

2 Answers

Type CustomTime time.Time

func (ct *CustomTime) UnmarshalParam(param string) error {
    t, err := time.Parse(`2006-01-02`, param)
    if err != nil {
        return err
    }
    *ct = CustomTime(t)
    return nil
}

ref: https://github.com/labstack/echo/issues/1571

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

  • query - source is request query parameters.
  • param - source is route path parameter.
  • header - source is header parameter.
  • form - source is form. Values are taken from query and request body. Uses Go standard library form parsing.
  • json - source is request body. Uses Go json package for unmarshalling.
  • xml - source is request body. Uses Go xml package for unmarshalling.

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"}'
Related