Ik heb onlangs met Go gespeeld en het is geweldig. Waar ik niet achter kan komen (na het doornemen van documentatie en blogposts) is hoe ik het type time.Time
kan laten formatteren in het formaat dat ik wil wanneer het is gecodeerd door json.NewEncoder.Encode
Hier is een minimaal codevoorbeeld:
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
}
}
Idealiter zou ik een verzoek willen sturen en het veld Stempel terug willen krijgen als iets als May 15, 2014
en niet 2014-05-16T08:28:06.801064-04:00
Maar ik weet niet precies hoe, ik weet dat ik json:stamp
kan toevoegen aan de declaratie van het documenttype om het veld te coderen met de naamstempel in plaats van met Stempel, maar ik doe dat niet Ik weet niet hoe dat soort dingen heten, dus ik weet niet eens waar ik op moet googlen om erachter te komen of daar ook een soort opmaakoptie in zit.
Heeft iemand een link naar een voorbeeld- of goede documentatiepagina over het onderwerp van die typemarkeringen (of hoe ze ook worden genoemd) of hoe ik de JSON-encoder kan vertellen om time.Time
velden?
Ter referentie heb ik deze pagina’s bekeken: hieren hieren natuurlijk, in de officiële documenten
Antwoord 1, autoriteit 100%
Wat u kunt doen is time.Time inpakken als uw eigen aangepaste type en ervoor zorgen dat de interface Marshaler
wordt geïmplementeerd:
type Marshaler interface {
MarshalJSON() ([]byte, error)
}
Dus wat je zou doen is zoiets als:
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
}
en maak document:
type Document struct {
Name string
Content string
Stamp JSONTime
Author string
}
en laat uw initialisatie er als volgt uitzien:
testDoc := model.Document{"Meeting Notes", "These are some notes", JSONTime(time.Now()), "Bacon"}
En dat is het zowat. Als je unmarshaling wilt, is er ook de Unmarshaler
-interface.
Antwoord 2, autoriteit 55%
Misschien is een andere manier interessant voor iemand. Ik wilde het aliastype voor Tijd vermijden.
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"),
})
}
Bron: http://choly.ca/post/go-json-marshalling/
Antwoord 3, autoriteit 30%
Ik zou NIET gebruiken:
type JSONTime time.Time
Ik zou het alleen voor primitieven gebruiken (string, int, …). In het geval van time.Time
wat een struct is, zou ik het elke keer moeten casten als ik een time.Time
methode wil gebruiken.
Ik zou dit in plaats daarvan doen (insluiten):
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
}
Het is niet nodig om t
naar tijd te casten. Het enige verschil is dat de nieuwe instantie NIET wordt gemaakt door JSONTime(time.Now())
maar door JSONTime{time.Now()}
Antwoord 4, autoriteit 6%
Maar ik weet niet precies hoe, ik weet dat ik json:stamp kan toevoegen aan de documenttypedeclaratie om het veld te coderen met de naamstempel in plaats van Stamp, maar ik weet niet wat die typen dingen worden genoemd, dus ik weet niet eens waar ik op moet googlen om erachter te komen of daar ook een soort opmaakoptie in zit.
Je bedoelt tags. Maar deze zullen je niet helpen met je opmaakprobleem.
De tekenreeksrepresentatie die u voor uw tijd krijgt, wordt geretourneerd door MarshalJSON
geïmplementeerd door Time
.
U kunt uw eigen MarshalJSON
-methode implementeren door de relevante bits te kopiëren uit de Time
implementatiedoor ofwel time.Time
in te sluiten of het inpakken. Inpakvoorbeeld (Klik om af te spelen):
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
}