Golang/Framework
[Gin] time Parsing 오류 -> 원하는 포맷으로 타임 바인딩하는 법
GenieLove!
2022. 11. 24. 23:51
728x90
반응형
time Parsing 오류
Gin Bind
func Test(c *Gin.Context) {
var body Body
if err := c.Bind(&body); err != nil {
c.JSON(400, err)
return
}
c.JSON(200, nil)
}
type Body sturct {
Birthday time.Time `json:"birthday" time_format:"2006-01-02 15:04:05"`
}
위에처럼 Body 구조체가 있을 때 Gin에서 Binding 시 string으로 된 birthday를 전달하게 되면 아래 오류가 발생한다.
parsing time "\"2016-01-02 15:04:05\"" as "\"2006-01-02T15:04:05Z07:00\"": cannot parse " 15:04:05\"" as "T"
인터넷 검색 시 많이 나오는 time_format 태그는 form 형식으로 바인딩할 때 사용하는 태그이므로 json 형식을 바인딩할 때는 에러가 발생한다.
Time Overriding
1. Body에서 Birthday 타입을 아래와 같이 바꿔준다.
type Body sturct {
Birthday NewTime `json:"birthday"`
}
2. UnmarshalJSON()을 오버라이딩 해주면 바인딩 시 기본 time 타입의 언마샬링이 아닌 오버라이딩한 함수로 작동되어 원하는 형식의 타임 포맷을 전달받을 수 있다.
3. MarshalJSON()을 오버라이딩해서 response 값도 원하는 포맷으로 할 수 있다. 처음엔 MarshalJSON도 포인터 리시버 함수로 작성했었는데 포인터 리시버 함수일 때는 작동하지 않는다.
type NewTime time.Time
func (n *NewTime) UnmarshalJSON(data []byte) (err error) {
var s string
err = json.Unmarshal(data, &s)
if err != nil {
return
}
location, err := time.LoadLocation("Asia/Seoul")
if err != nil {
return
}
/* location 사용 안 할 때는
t, err := time.Parse("2006-01-02 15:04:05")
if err != nil {
return
}
t, err := time.ParseInLocation("2006-01-02 15:04:05", s, location)
*/
*n = NewTime(t)
return
}
func (n NewTime) MarshalJSON() ([]byte, error) {
t := time.Time(n)
if y := t.Year(); y < 0 || y >= 10000 {
// RFC 3339 is clear that years are 4 digits exactly.
// See golang.org/issue/4556#c15 for more discussion.
return nil, errors.New("Time.MarshalJSON: year outside of range [0,9999]")
}
b := make([]byte, 0, len("2006-01-02 15:04:05")+2)
b = append(b, '"')
b = t.AppendFormat(b, "2006-01-02 15:04:05")
b = append(b, '"')
return b, nil
}
728x90
반응형