私は最近Goで遊んでいますが、すごいです。 (ドキュメントやブログの投稿を見て)理解できないように思えるのは、time.Time
タイプを取得して、json.NewEncoder.Encode
でエンコードされたときに好きなフォーマットにフォーマットする方法です。
最小限のコード例を次に示します。
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
}
}
理想的には、リクエストを送信し、May 15, 2014
ではなく2014-05-16T08:28:06.801064-04:00
のようなStampフィールドを取得したいです。
しかし、私は本当にわからない、json:stamp
をDocument型宣言に追加して、スタンプではなく名前スタンプでエンコードされるフィールドを取得できることを知っているが、それらのタイプのことはわからないと呼ばれるので、その中に何らかの形式のオプションが同様にあるかどうかを調べるために何をグーグルで検索するべきかさえわかりません。
それらのタイプマークアップ(またはそれらが呼び出されるもの)の件名またはtime.Time
フィールドを処理するようJSONエンコーダーに指示する方法について、誰かが例または良いドキュメントページへのリンクを持っていますか?
できることは、time.Timeを独自のカスタムタイプとしてラップし、Marshaler
インターフェイスを実装することです。
type Marshaler interface {
MarshalJSON() ([]byte, error)
}
だからあなたがすることは次のようなものです:
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
}
文書を作成します。
type Document struct {
Name string
Content string
Stamp JSONTime
Author string
}
初期化は次のようになります。
testDoc := model.Document{"Meeting Notes", "These are some notes", JSONTime(time.Now()), "Bacon"}
そしてそれはそれについてです。アンマーシャリングが必要な場合は、Unmarshaler
インターフェイスもあります。
おそらく別の方法が誰かにとって興味深いでしょう。 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"),
})
}
私は使用しません:
_type JSONTime time.Time
_
プリミティブ(string、int、...)にのみ使用します。構造体である_time.Time
_の場合、_time.Time
_メソッドを使用するたびにキャストする必要があります。
私は代わりにこれを行います(埋め込み):
_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
}
_
t
を時間にキャストする必要はありません。唯一の違いは、新しいインスタンスはJSONTime(time.Now())
ではなくJSONTime{time.Now()}
によって作成されることです
しかし、私は本当にわからない、json:stampをDocument型宣言に追加して、スタンプではなく名前スタンプでフィールドをエンコードすることができることを知っていますが、それらのタイプの名前がわからない、そのため、その中に何らかの形式のオプションがあるかどうかを調べるために何をグーグルで検索するべきかさえ分かりません。
つまり、 タグ です。しかし、これらはフォーマットの問題には役立ちません。
取得した文字列表現は、 MarshalJSON
によって返されます Time
によって実装されます。
time.Time
を埋め込むか、または MarshalJSON
implementation から関連するビットをコピーすることにより、独自のTime
メソッドを実装できます。それを包みます。ラッピングの例( クリックして再生 ):
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
}