Essayer de json Marshal une structure qui contient 2 champs de temps. Mais je veux que le champ ne passe que s'il a une valeur de temps. J'utilise donc json:",omitempty"
mais ça ne marche pas.
Que puis-je définir pour que la valeur Date soit json.Marshal la traitera comme une valeur vide (zéro) et ne l'inclura pas dans la chaîne json?
Aire de jeux: http://play.golang.org/p/QJwh7yBJlo
Résultat réel:
{"Horodatage": "2015-09-18T00: 00: 00Z", "Date": "0001-01-01T00: 00: 00Z"}
Résultat souhaité:
{"Horodatage": "2015-09-18T00: 00: 00Z"}
Code:
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))
}
L'option de balise omitempty
ne fonctionne pas avec time.Time
Car c'est un struct
. Il y a une valeur "zéro" pour les structures, mais c'est une valeur de structure où tous les champs ont leurs valeurs nulles. Il s'agit d'une valeur "valide", elle n'est donc pas traitée comme "vide".
Mais en le changeant simplement en un pointeur: *time.Time
, Cela fonctionnera (nil
les pointeurs sont traités comme "vides" pour json marshaling/unmarshaling). Donc pas besoin d'écrire personnalisé Marshaler
dans ce cas:
type MyStruct struct {
Timestamp *time.Time `json:",omitempty"`
Date *time.Time `json:",omitempty"`
Field string `json:",omitempty"`
}
En l'utilisant:
ts := time.Date(2015, 9, 18, 0, 0, 0, 0, time.UTC)
ms := MyStruct{
Timestamp: &ts,
Field: "",
}
Sortie (comme souhaité):
{"Timestamp":"2015-09-18T00:00:00Z"}
Essayez-le sur le Go Playground .
Si vous ne pouvez pas ou ne voulez pas le changer en pointeur, vous pouvez toujours obtenir ce que vous voulez en implémentant un Marshaler
et Unmarshaler
. Si vous le faites, vous pouvez utiliser la méthode Time.IsZero()
pour décider si une valeur time.Time
Est la valeur zéro.
vous pouvez définir votre propre type d'heure pour le format de marshal personnalisé et l'utiliser partout à la place 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)
}