受到 zeebo 答案的启发并在该答案的评论中进行了讨论:
http://play.golang.org/p/pUCBUgrjZC
package main
import "fmt"
import "time"
import "encoding/json"
type jsonTime struct {
time.Time
f string
}
func (j jsonTime) format() string {
return j.Time.Format(j.f)
}
func (j jsonTime) MarshalText() ([]byte, error) {
return []byte(j.format()), nil
}
func (j jsonTime) MarshalJSON() ([]byte, error) {
return []byte(`"` + j.format() + `"`), nil
}
func main() {
jt := jsonTime{time.Now(), time.Kitchen}
if jt.Before(time.Now().AddDate(0, 0, 1)) { // 1
x := map[string]interface{}{
"foo": jt,
"bar": "baz",
}
data, err := json.Marshal(x)
if err != nil {
panic(err)
}
fmt.Printf("%s", data)
}
}
这个解决方案embeds将 time.Time 放入 jsonTime 结构中。嵌入将所有 time.Time 的方法提升为 jsonTime 结构,允许在没有显式类型转换的情况下使用它们(请参阅 // 1)。
嵌入 time.Time 的缺点是还会提升 MarshalJSON 方法,出于向后兼容性的原因,encoding/json 编组代码优先级高于 MarshalText 方法(MarshalText 是在 Go 1.2 中添加的,MarshalJSON 早于此)。因此,使用默认的 time.Time 格式而不是 MarshalText 提供的自定义格式。
为了解决这个问题,我们重写 jsonTime 结构的 MarshalJSON。