Search code examples
datetimegostructgo-gin

How should I get string datetime from API and unmarshal it into struct time.Time field in Gonic?


I use gin context to get json data and convert it into struct, it works fine. But what I have issues with is using time.Time as one of the field types:

type User struct {
    CreatedAt  time.Time `json:"created_at"`
}

In gin I use ShouldBind:

  var user User
  if err := c.ShouldBind(&user); err != nil {
        c.JSON(200, g.H{})
        return
  }

The error I get is:

parsing time "2019-01-01T00:00:00" as "2006-01-02T15:04:05Z07:00": cannot parse "" as "Z07:00"

It seems that timezone segment is required. I also gave Z00:00 but again parse error raised.

How I can get datetime like "2022-01-01 20:00:00" and convert it into time.Time in Go or even with timezone?


Solution

  • func HandleTime(c *gin.Context) {
        type User struct {
            CreatedAt time.Time `json:"created_at" binding:"required" time_format:"2006-01-02T15:04:05Z07:00"`
        }
        var user User
        fmt.Println(user.CreatedAt.String())
        if err := c.ShouldBindJSON(&user); err != nil {
            fmt.Println(err)
            return
        }
        c.JSON(200, gin.H{
            "created": user.CreatedAt.String(),
        })
    }
    
    curl -X POST 'http://127.0.0.1:8092/${YOUR_PATH}' \
    -H 'Content-Type: application/json' -d '{
        "created_at": "2019-01-01T01:00:09+08:00"
    }'
    

    Response:

    {
        "created": "2019-01-01 01:00:09 +0800 CST"
    }
    

    See this in go doc: https://pkg.go.dev/time@go1.18.4#example-Parse

    For example the RFC3339 layout 2006-01-02T15:04:05Z07:00 contains both Z and a time zone offset in order to handle both valid options:

    • 2006-01-02T15:04:05Z
    • 2006-01-02T15:04:05+07:00.