How to format timestamp in outgoing JSON

后端 未结 4 1932
佛祖请我去吃肉
佛祖请我去吃肉 2020-11-29 18:11

I\'ve been playing with Go recently and it\'s awesome. The thing I can\'t seem to figure out (after looking through documentation and blog posts) is how to get the tim

相关标签:
4条回答
  • 2020-11-29 18:34

    Perhaps another way will be interesting for someone. I wanted to avoid using alias type for 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"),
        })
    }
    

    Source: http://choly.ca/post/go-json-marshalling/

    0 讨论(0)
  • 2020-11-29 18:51

    I would NOT use:

    type JSONTime time.Time
    

    I would use it only for primitives (string, int, ...). In case of time.Time which is a struct, I would need to cast it every time I want to use any time.Time method.

    I would do this instead (embedding):

    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
    }
    

    No need to cast t to time. The only difference is that new instance is NOT created by JSONTime(time.Now()) but by JSONTime{time.Now()}

    0 讨论(0)
  • 2020-11-29 18:55

    What you can do is, wrap time.Time as your own custom type, and make it implement the Marshaler interface:

    type Marshaler interface {
        MarshalJSON() ([]byte, error)
    }
    

    So what you'd do is something like:

    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
    }
    

    and make document:

    type Document struct {
        Name        string
        Content     string
        Stamp       JSONTime
        Author      string
    }
    

    and have your intialization look like:

     testDoc := model.Document{"Meeting Notes", "These are some notes", JSONTime(time.Now()), "Bacon"}    
    

    And that's about it. If you want unmarshaling, there is the Unmarshaler interface too.

    0 讨论(0)
  • 2020-11-29 18:55

    But I'm not really sure how, I know I can add json:stamp to the Document type declaration to get the field to be encoded with the name stamp instead of Stamp, but I don't know what those types of things are called, so I'm not even sure what to google for to find out if there is some type of formatting option in that as well.

    You mean tags. But these won't help you with your formatting problem.

    The string representation you get for your time is returned by MarshalJSON implemented by Time.

    You can go ahead and implement your own MarshalJSON method by copying the relevant bits from the Time implementation by either embedding time.Time or wrapping it. Wrapping example (Click to play):

    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
    }
    
    0 讨论(0)
提交回复
热议问题