在Golang中传出JSON中的格式时间戳?

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界面.

  • 但是,这不允许使用“时间”包中的所有其他功能,例如“之后”和“之前”。 (2认同)
  • @DejoriDavid你只需要把它转回`time.Time`来做那个:`time.Time(myJsonTime).After(...` (2认同)

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()}


nem*_*emo 5

但是我不确定如何,我知道我可以在文档类型声明中添加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)