Je joue avec Go récemment et c'est génial. La seule chose que je n'arrive pas à comprendre (après avoir consulté la documentation et les billets de blog) est comment obtenir le time.Time
taper pour formater le format que je voudrais quand il est encodé par json.NewEncoder.Encode
Voici un exemple de code minimal:
package main
type Document struct {
Name string
Content string
Stamp time.Time
Author string
}
func sendResponse(data interface{}, w http.ResponseWriter, r * http.Request){
_, err := json.Marshal(data)
j := json.NewEncoder(w)
if err == nil {
encodedErr := j.Encode(data)
if encodedErr != nil{
//code snipped
}
}else{
//code snipped
}
}
func main() {
http.HandleFunc("/document", control.HandleDocuments)
http.ListenAndServe("localhost:4000", nil)
}
func HandleDocuments(w http.ResponseWriter,r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
switch r.Method {
case "GET":
//logic snipped
testDoc := model.Document{"Meeting Notes", "These are some notes", time.Now(), "Bacon"}
sendResponse(testDoc, w,r)
}
case "POST":
case "PUT":
case "DELETE":
default:
//snipped
}
}
Idéalement, j'aimerais envoyer une demande et obtenir le champ Timbre comme suit: May 15, 2014
et pas 2014-05-16T08:28:06.801064-04:00
Mais je ne sais pas trop comment, je sais que je peux ajouter json:stamp
à la déclaration de type de document pour que le champ soit encodé avec le nom stamp au lieu de stamp, mais je ne sais pas comment ces types s'appellent, donc je ne suis même pas sûr de ce qu'il faut rechercher sur Google s’il existe également un type d’option de formatage.
Quelqu'un a-t-il un lien vers un exemple ou une bonne page de documentation sur le sujet de ces balises (ou le nom de la balise) ou sur la façon dont je peux dire à l'encodeur JSON de gérer time.Time
des champs?
Juste pour référence, j'ai regardé ces pages: ici et ici et bien sûr, aux documents officiels
Ce que vous pouvez faire est, encapsulez time.Time comme votre propre type personnalisé et faites-le implémenter l'interface Marshaler
:
type Marshaler interface {
MarshalJSON() ([]byte, error)
}
Donc, ce que vous feriez est quelque chose comme:
type JSONTime time.Time
func (t JSONTime)MarshalJSON() ([]byte, error) {
//do your serializing here
stamp := fmt.Sprintf("\"%s\"", time.Time(t).Format("Mon Jan _2"))
return []byte(stamp), nil
}
et faire un document:
type Document struct {
Name string
Content string
Stamp JSONTime
Author string
}
et que votre initiation ressemble à:
testDoc := model.Document{"Meeting Notes", "These are some notes", JSONTime(time.Now()), "Bacon"}
Et c'est à peu près tout. Si vous souhaitez supprimer le métissage, il existe également l'interface Unmarshaler
.
Peut-être qu'une autre façon sera intéressante pour quelqu'un. Je voulais éviter d'utiliser le type d'alias pour Time.
type Document struct {
Name string
Content string
Stamp time.Time
Author string
}
func (d *Document) MarshalJSON() ([]byte, error) {
type Alias Document
return json.Marshal(&struct {
*Alias
Stamp string `json:"stamp"`
}{
Alias: (*Alias)(d),
Stamp: d.Stamp.Format("Mon Jan _2"),
})
}
Je ne voudrais pas utiliser:
type JSONTime time.Time
Je ne l'utiliserais que pour les primitives (string, int, ...). Dans le cas de time.Time
Qui est une structure, je devrais le lancer à chaque fois que je veux utiliser une méthode time.Time
.
Je ferais ceci à la place (intégration):
type JSONTime struct {
time.Time
}
func (t JSONTime)MarshalJSON() ([]byte, error) {
//do your serializing here
stamp := fmt.Sprintf("\"%s\"", t.Format("Mon Jan _2"))
return []byte(stamp), nil
}
Pas besoin de lancer t
à temps. La seule différence est que la nouvelle instance n'est PAS créée par JSONTime(time.Now())
mais par JSONTime{time.Now()}
Mais je ne sais pas trop comment, je sais que je peux ajouter json: stamp à la déclaration de type de document pour que le champ soit codé avec le tampon de nom au lieu de tampon, mais je ne sais pas comment ces types de choses s'appellent. Je ne sais même pas quoi chercher sur Google pour savoir s’il existe également une option de formatage.
Vous voulez dire tags . Mais cela ne vous aidera pas avec votre problème de formatage.
La représentation sous forme de chaîne que vous obtenez pour votre temps est retournée par MarshalJSON
implémenté par Time
.
Vous pouvez aller de l'avant et implémenter votre propre méthode MarshalJSON
en copiant les bits pertinents de l'implémentation de Time
en incorporant time.Time
ou l'envelopper. Exemple de wrapping ( Cliquez pour lire ):
type ShortDateFormattedTime time.Time
func (s ShortDateFormattedTime) MarshalJSON() ([]byte, error) {
t := time.Time(s)
if y := t.Year(); y < 0 || y >= 10000 {
return nil, errors.New("Time.MarshalJSON: year outside of range [0,9999]")
}
return []byte(t.Format(`"Jan 02, 2006"`)), nil
}