gin-gonic / gin

Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.
https://gin-gonic.com/
MIT License
78.88k stars 8.02k forks source link

time_format tag not work with ShouldBindJSON? #2170

Open axiaoxin opened 4 years ago

axiaoxin commented 4 years ago

Description

I have the param struct like this:

type Param1 struct {
    Timestamp time.Time `json:"Timestamp" binding:"required" time_format:"2006-01-02 15:04:05"`
}

type Param2 struct {
    Timestamp time.Time `json:"Timestamp" binding:"required" time_format:"unix"`
}

request json for Param1:

{
    "Timestamp": "2001-11-11 11:11:11"
}

response error:

parsing time \"\"2001-11-11 11:11:11\"\" as \"\"2006-01-02T15:04:05Z07:00\"\": cannot parse \" 11:11:11\"\" as \"T\"]

request json for Param2:

{
     "Timestamp": 1575528300
}

response error:

parsing time \"1575528300\" as \"\"2006-01-02T15:04:05Z07:00\"\": cannot parse \"1575528300\" as \"\"\"]

Environment

yahuian commented 4 years ago

@axiaoxin Maybe this can help you #1193

mreddimasi commented 4 years ago

This seems to be a bug, maybe some one in the community can confirm:

Followed the instructions in Bind Query or POST Data

package main

import (
    "log"
    "time"

    "github.com/gin-gonic/gin"
)

type Person struct {
    JoiningDate    time.Time `form:"joining_date" time_format:"2006-01-02" time_utc:"1"`
    FeeAmount      uint64    `form:"fee_amount"`
}

func main() {
    route := gin.Default()
    route.GET("/testing", startPage)
    route.Run(":8085")
}

func startPage(c *gin.Context) {
    var person Person
    // If `GET`, only `Form` binding engine (`query`) used.
    // If `POST`, first checks the `content-type` for `JSON` or `XML`, then uses `Form` (`form-data`).
    // See more at https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48
    if c.ShouldBind(&person) == nil {
        log.Println(person.JoiningDate)
        log.Println(person.FeeAmount)

    }

    c.String(200, "Success")
}

Executing the request curl -X GET "localhost:8085/testing?joining_date=1992-03-15"

prints the following:

2020/03/03 23:16:52 1992-03-15 00:00:00 +0000 UTC

But when we change the GET to POST and execute the curl:

curl -X POST localhost:8085/testing --header 'Content-Type: application/json' --data-raw '{"joining_date": "2020-03-03","fee_amount": 100 }'

prints the following:

2020/03/03 23:19:48 0001-01-01 00:00:00 +0000 UTC

Environment:

mreddimasi commented 4 years ago

It looks like we have to declare the struct as follows

type Person struct {
    JoiningDate    time.Time `json:"joining_date"` 
    FeeAmount      uint64    `form:"fee_amount"`
}

And then pass in the date value in format of RFC3339 when using POST

netxixi commented 3 years ago

If your date =2021-02-02, you can submit the date = 2021-02-02T00:00:00Z