JSON은 공백으로 되어 있습니다.시간 필드
2개의 타임필드를 포함하는 구조체의 마셜링을 시도하고 있습니다.하지만 시간 값이 있는 필드만 통과했으면 합니다.그래서 지금 쓰고 있어요.json:",omitempty"
효과가 없어요.
날짜 값을 so json으로 설정할 수 있는 것은 무엇입니까?Marshal은 그것을 빈 값(0)으로 취급하고 json 문자열에 포함하지 않습니까?
Playground : http://play.golang.org/p/QJwh7yBJlo
실제 결과:
{'타임 스탬프':2015-09-18T00:00:00Z", "날짜":0001-01-01T00:00Z"}
바람직한 결과:
{'타임 스탬프':2015-09-18T00:00:00Z"}
코드:
package main
import (
"encoding/json"
"fmt"
"time"
)
type MyStruct struct {
Timestamp time.Time `json:",omitempty"`
Date time.Time `json:",omitempty"`
Field string `json:",omitempty"`
}
func main() {
ms := MyStruct{
Timestamp: time.Date(2015, 9, 18, 0, 0, 0, 0, time.UTC),
Field: "",
}
bb, err := json.Marshal(ms)
if err != nil {
panic(err)
}
fmt.Println(string(bb))
}
그omitempty
태그 옵션은 와 함께 동작하지 않습니다.time.Time
이지만struct
. 구조체에는 "0" 값이 있지만 모든 필드에 0 값이 있는 구조체 값입니다.이 값은 "유효한" 값이므로 "빈"으로 처리되지 않습니다.
그러나 단순히 포인터로 변경하는 것만으로:*time.Time
동작합니다(nil
포인터는 json 마샬링/언마샬링의 경우 "empty"로 취급됩니다.따라서 이 경우 커스텀을 쓸 필요가 없습니다.
type MyStruct struct {
Timestamp *time.Time `json:",omitempty"`
Date *time.Time `json:",omitempty"`
Field string `json:",omitempty"`
}
사용방법:
ts := time.Date(2015, 9, 18, 0, 0, 0, 0, time.UTC)
ms := MyStruct{
Timestamp: &ts,
Field: "",
}
출력(필요한 경우):
{"Timestamp":"2015-09-18T00:00:00Z"}
바둑 놀이터에서 시도해 보세요.
포인터로 변경할 수 없거나 포인터로 변경할 수 없는 경우에도 커스텀과 를 실장하면 원하는 것을 실현할 수 있습니다.이 경우 이 방법을 사용하여 다음 중 하나를 선택할 수 있습니다.time.Time
value는 제로 값입니다.
커스텀 marshal 포맷에 대한 자체 시간 유형을 정의하고 대신 어디에서나 사용할 수 있습니다.time.Time
https://play.golang.org/p/C8nIR1uZAok
package main
import (
"bytes"
"encoding/json"
"fmt"
"time"
)
type MyTime struct {
*time.Time
}
func (t MyTime) MarshalJSON() ([]byte, error) {
return []byte(t.Format("\"" + time.RFC3339 + "\"")), nil
}
// UnmarshalJSON implements the json.Unmarshaler interface.
// The time is expected to be a quoted string in RFC 3339 format.
func (t *MyTime) UnmarshalJSON(data []byte) (err error) {
// by convention, unmarshalers implement UnmarshalJSON([]byte("null")) as a no-op.
if bytes.Equal(data, []byte("null")) {
return nil
}
// Fractional seconds are handled implicitly by Parse.
tt, err := time.Parse("\""+time.RFC3339+"\"", string(data))
*t = MyTime{&tt}
return
}
func main() {
t := time.Now()
d, err := json.Marshal(MyTime{&t})
fmt.Println(string(d), err)
var mt MyTime
json.Unmarshal(d, &mt)
fmt.Println(mt)
}
icza의 답변의 후속으로 빈 날짜 필드는 생략하고 나머지 필드는 변경하지 않는 커스텀 마샬러가 있습니다.
func (ms *MyStruct) MarshalJSON() ([]byte, error) {
type Alias MyStruct
if ms.Timestamp.IsZero() {
return json.Marshal(&struct {
Timestamp int64 `json:",omitempty"`
*Alias
}{
Timestamp: 0,
Alias: (*Alias)(ms),
})
} else {
return json.Marshal(&struct {
*Alias
}{
Alias: (*Alias)(ms),
})
}
}
이것은 http://choly.ca/post/go-json-marshalling/ 에서 차용한 것입니다.
OPs 케이스에는 두 개의 시간 필드가 있어 훨씬 더 복잡해집니다.(둘 다 비어 있지 않은지 확인해야 합니다.)
이를 달성하기 위한 더 나은 방법이 있을 수 있으므로 코멘트는 환영합니다.
언급URL : https://stackoverflow.com/questions/32643815/json-omitempty-with-time-time-field
'programing' 카테고리의 다른 글
Angular는 어떻게 알아?JS를 "갱신"하다 (0) | 2023.03.02 |
---|---|
Angularjs의 $http 사용 시 응답 헤더 읽기 (0) | 2023.03.02 |
리액트 컴포넌트 동적 렌더링 (0) | 2023.03.02 |
json 파일 설명 추가 (0) | 2023.03.02 |
html5의 소스 "src" 속성을 변경해도 angularjs에는 적용되지 않습니다. (0) | 2023.03.02 |