2つの時間フィールドを含む構造体をjsmarshalしようとしています。しかし、時間の値がある場合にのみ、フィールドが通過するようにします。だから私はjson:",omitempty"
を使用していますが、機能していません。
Date値をjson.Marshalが空(ゼロ)値として扱い、json文字列に含めないように設定するにはどうすればよいですか?
遊び場: http://play.golang.org/p/QJwh7yBJlo
実際の結果:
{「タイムスタンプ」:「2015-09-18T00:00:00Z」、「日付」:「0001-01-01T00:00: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
タグオプションは、struct
であるため、_time.Time
_では機能しません。構造体には「ゼロ」値がありますが、それはすべてのフィールドにゼロ値がある構造体値です。これは「有効な」値なので、「空」として扱われません。
しかし、ポインタを_*time.Time
_に変更するだけで機能します(nil
ポインタは、jsonマーシャリング/アンマーシャリングでは「空」として扱われます)。この場合、カスタム Marshaler
を記述する必要はありません。
_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"}
_
Go Playground で試してください。
ポインタに変更できない、または変更したくない場合でも、カスタム Marshaler
および Unmarshaler
。その場合、 Time.IsZero()
メソッドを使用して、_time.Time
_値がゼロ値であるかどうかを判断できます。
カスタムマーシャル形式の自己時間型を定義し、代わりにどこでも使用できますtime.Time
http://play.golang.org/p/S9VIWNAaVS
package main
import "fmt"
import "time"
import "encoding/json"
type MyTime struct{
*time.Time
}
func (t MyTime) MarshalJSON() ([]byte, error) {
return []byte(t.Format("\"2006-01-02T15:04:05Z\"")), 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) {
// Fractional seconds are handled implicitly by Parse.
tt, err := time.Parse("\"2006-01-02T15:04:05Z\"", 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)
}