2013-12-09 8 views
7

In Golang, esiste un modo per utilizzare lo strumento generico encoding/json Marshal per utilizzare un layout diverso quando si effettua il marshalling dei campi time.Time?Sovrascrivi il layout utilizzato da json.Marshal per formattare l'ora. Tempo

Fondamentalmente ho questo struct:

s := {"starttime":time.Now(), "name":"ali"} 

e voglio codifica a JSON utilizzando la funzione 's encdoding/jsonMarshal, ma voglio usare il mio layout personalizzato, immagino qualche time.Format(layout) viene chiamato, voglio per controllare tale layout,

risposta

10

Come ispirato dalla risposta di zeebo e hash nei commenti a questa risposta:

http://play.golang.org/p/pUCBUgrjZC

package main 

import "fmt" 
import "time" 
import "encoding/json" 

type jsonTime struct { 
    time.Time 
    f string 
} 

func (j jsonTime) format() string { 
    return j.Time.Format(j.f) 
} 

func (j jsonTime) MarshalText() ([]byte, error) { 
    return []byte(j.format()), nil 
} 

func (j jsonTime) MarshalJSON() ([]byte, error) { 
    return []byte(`"` + j.format() + `"`), nil 
} 

func main() { 
    jt := jsonTime{time.Now(), time.Kitchen} 
    if jt.Before(time.Now().AddDate(0, 0, 1)) { // 1 
     x := map[string]interface{}{ 
      "foo": jt, 
      "bar": "baz", 
     } 
     data, err := json.Marshal(x) 
     if err != nil { 
      panic(err) 
     } 
     fmt.Printf("%s", data) 
    } 
} 

Questa soluzione embeds la time.time nella struct jsonTime. L'incorporamento promuove tutto il tempo. Metodi di tempo per la struttura jsonTime, consentendo il loro uso senza conversione di tipo esplicita (vedi // 1).

Incorporare un orario. Il tempo ha lo svantaggio di promuovere anche il metodo MarshalJSON, che il codice di codifica/json marshalling dà priorità al metodo MarshalText per ragioni di compatibilità all'indietro (MarshalText was added in Go 1.2, MarshalJSON è anteriore a tale). Di conseguenza l'ora predefinita. Il formato del tempo viene utilizzato al posto di un formato personalizzato fornito da MarshalText.

Per risolvere questo problema, ignoriamo MarshalJSON per la struttura jsonTime.

+0

come faresti a rispettare questo "omitempty" nel campo del tempo? – nojo

6

Forse qualcosa del genere funzionerà per te?

package main 

import "fmt" 
import "time" 
import "encoding/json" 

type jsonTime struct { 
t time.Time 
f string 
} 

func (j jsonTime) MarshalText() ([]byte, error) { 
return []byte(j.t.Format(j.f)), nil 
} 

func main() { 
x := map[string]interface{}{ 
    "foo": jsonTime{t: time.Now(), f: time.Kitchen}, 
    "bar": "baz", 
} 
data, err := json.Marshal(x) 
if err != nil { 
    panic(err) 
} 
fmt.Printf("%s", data) 
} 

disponibile anche qui: http://play.golang.org/p/D1kq5KrXQZ

Basta fare un tipo personalizzato che implementa MarshalText il modo in cui si desidera vedere.

+0

Grazie, Questo è sicuramente un passo avanti, ma vorrei non dover convertire tutti i 'time.Time's a' mytime' e ritorno ogni volta che voglio usare un tempo.Dopo o tempo.Prima .. – Ali

+1

Se si desidera chiamare time.Time metodi sul tipo personalizzato, quindi incorporare un'ora. Tempo invece di dargli un nome. per esempio. http://play.golang.org/p/Vudw0hhnwe – ChrisH

+0

A meno che non mi sbagli molto, se incorporo il 'time.Time', allora il' MarshalText' non funzionerà per la codifica json, che è stata la ragione per tutti questo per cominciare. Ha bisogno di essere nominato. – Ali

3

Innanzitutto, mi raccomando di non utilizzare un formato orario diverso da quello predefinito RFC3339. È un formato di tempo utile e può essere analizzato da un numero qualsiasi di lingue, quindi, a meno che non sia necessario un formato diverso perché l'API di qualcun altro lo richiede, è probabilmente meglio utilizzare l'impostazione predefinita.

Ma, ho dovuto risolvere questo problema nel consumare le API di altre persone, ecco una soluzione che sposta il grosso del lavoro per il/step Unmarshal maresciallo, e ti lascia con una struttura ideale: http://play.golang.org/p/DKaTbV2Zvl

+0

In che modo RFC3339 è migliore di qualsiasi altro? (ad es. RFC822Z) – themihai

Problemi correlati