unmarshal print marshal lib lab handling golang deserialize and json go time struct

print - Golang JSON omitempty With time.Time Field



json to struct golang (2)

Intentando json Marshal una estructura que contiene 2 campos de tiempo. Pero solo quiero que el campo aparezca si tiene un valor de tiempo. Así que estoy usando json:",omitempty" pero no está funcionando.

¿Cómo puedo configurar el valor de Fecha para que json.Marshal lo trate como un valor vacío (cero) y no lo incluya en la cadena json?

Zona de juegos: http://play.golang.org/p/QJwh7yBJlo

Resultado real:

{"Marca de tiempo": "2015-09-18T00: 00: 00Z", "Fecha": "0001-01-01T00: 00: 00Z"}

Resultado deseado:

{"Marca de tiempo": "2015-09-18T00: 00: 00Z"}

Código:

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)) }


La opción de etiqueta omitempty no funciona con time.Time ya que es una struct . Hay un valor "cero" para las estructuras, pero ese es un valor de estructura donde todos los campos tienen sus valores cero. Este es un valor "válido", por lo que no se trata como "vacío".

Pero simplemente cambiándolo a un puntero: *time.Time , funcionará (los punteros nil se tratan como "vacíos" para json marshaling / unmarshaling). Así que no hay necesidad de escribir Marshaler personalizado en este caso:

type MyStruct struct { Timestamp *time.Time `json:",omitempty"` Date *time.Time `json:",omitempty"` Field string `json:",omitempty"` }

Usandolo

ts := time.Date(2015, 9, 18, 0, 0, 0, 0, time.UTC) ms := MyStruct{ Timestamp: &ts, Field: "", }

Salida (como se desee):

{"Timestamp":"2015-09-18T00:00:00Z"}

Pruébalo en el Go Playground .

Si no puede o no desea cambiarlo a un puntero, aún puede lograr lo que desea mediante la implementación de Marshaler y Unmarshaler . Si lo hace, puede usar el método Time.IsZero() para decidir si un valor de time.Time es el valor cero.


puede definir su propio tipo de hora para el formato de mariscal personalizado y utilizarlo en cualquier lugar en lugar de la 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) }