Edg*_*erg 46 formatting time json go
我最近一直在玩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
}
}
Run Code Online (Sandbox Code Playgroud)
理想情况下,我想发送一个请求并将Stamp字段恢复为喜欢May 15, 2014与否2014-05-16T08:28:06.801064-04:00
但是我不知道如何,我知道我可以添加json:stamp到Document类型声明来使用名称戳而不是Stamp来编码字段,但我不知道这些类型的东西被调用了什么,所以我我甚至不确定谷歌要知道是否还有某种类型的格式化选项.
有没有人有关于那些类型标记(或者他们被称为)的主题的示例或良好文档页面的链接,或者我如何告诉JSON编码器处理time.Time字段?
Not*_*fer 87
你可以做的是,将time.Time包装为你自己的自定义类型,并使它实现Marshaler接口:
type Marshaler interface {
MarshalJSON() ([]byte, error)
}
Run Code Online (Sandbox Code Playgroud)
所以你要做的是:
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
}
Run Code Online (Sandbox Code Playgroud)
并制作文件:
type Document struct {
Name string
Content string
Stamp JSONTime
Author string
}
Run Code Online (Sandbox Code Playgroud)
你的初始化看起来像:
testDoc := model.Document{"Meeting Notes", "These are some notes", JSONTime(time.Now()), "Bacon"}
Run Code Online (Sandbox Code Playgroud)
这就是它.如果你想要解组,也有Unmarshaler界面.
s7a*_*ley 44
也许另一种方式对某人来说会很有趣.我想避免为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"),
})
}
Run Code Online (Sandbox Code Playgroud)
资料来源:http://choly.ca/post/go-json-marshalling/
小智 17
我不会用:
type JSONTime time.Time
Run Code Online (Sandbox Code Playgroud)
我只会将它用于原语(string,int,...).如果time.Time是struct,我需要在每次想要使用任何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
}
Run Code Online (Sandbox Code Playgroud)
无需投入t时间.唯一的区别是新实例不是由...创建JSONTime(time.Now())的JSONTime{time.Now()}
但是我不确定如何,我知道我可以在文档类型声明中添加json:stamp以获得使用名称戳而不是戳进行编码的字段,但是我不知道这些类型的东西叫什么,所以我什至不知道该搜索什么,以了解是否还有某种格式设置选项。
你是说标签。但是这些不会帮助您解决格式问题。
您所获得的字符串表示形式由MarshalJSON实现返回Time。
您可以通过嵌入或包装实现来MarshalJSON复制实现中的相关位,从而继续实现自己的方法。包装示例(单击播放):Timetime.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
}
Run Code Online (Sandbox Code Playgroud)