[英]How to unmarshal JSON into durations?
What is the idiomatic way to unmarshal into time.Duration
in Go?在 Go 中解组
time.Duration
的惯用方法是什么? How can I make use of time.ParseDuration
?我怎样才能利用
time.ParseDuration
?
The lack of JSON marshaling and unmarshaling methods on time.Duration
was an unfortunate oversight.没有及时的 JSON 编组和解组方法
time.Duration
是一个不幸的疏忽。 This should hopefully be resolved in Go2 ( see issue #10275 ).这有望在 Go2 中得到解决(请参阅问题 #10275 )。
You can, however, define your own type around time.Duration
that supports marshaling to the string representation of the duration and unmarshaling from either the numeric or string representations.但是,您可以在
time.Duration
周围定义自己的类型,该类型支持编组为持续时间的字符串表示形式并从数字或字符串表示形式解组。 Here is an example of such an implementation:以下是此类实现的示例:
package main
import (
"encoding/json"
"errors"
"fmt"
"time"
)
type Duration struct {
time.Duration
}
func (d Duration) MarshalJSON() ([]byte, error) {
return json.Marshal(d.String())
}
func (d *Duration) UnmarshalJSON(b []byte) error {
var v interface{}
if err := json.Unmarshal(b, &v); err != nil {
return err
}
switch value := v.(type) {
case float64:
d.Duration = time.Duration(value)
return nil
case string:
var err error
d.Duration, err = time.ParseDuration(value)
if err != nil {
return err
}
return nil
default:
return errors.New("invalid duration")
}
}
type Message struct {
Elapsed Duration `json:"elapsed"`
}
func main() {
msgEnc, err := json.Marshal(&Message{
Elapsed: Duration{time.Second * 5},
})
if err != nil {
panic(err)
}
fmt.Printf("%s\n", msgEnc)
var msg Message
if err := json.Unmarshal([]byte(`{"elapsed": "1h"}`), &msg); err != nil {
panic(err)
}
fmt.Printf("%#v\n", msg)
}
https://play.golang.org/p/Zm6hpNR-ZJ2 https://play.golang.org/p/Zm6hpNR-ZJ2
Just to extend the previous answer.只是为了扩展以前的答案。 There is another way (very close to Tim's)
还有另一种方式(非常接近蒂姆的)
type Duration time.Duration
func (d Duration) MarshalJSON() ([]byte, error) {
return json.Marshal(time.Duration(d).String())
}
func (d *Duration) UnmarshalJSON(b []byte) error {
var v interface{}
if err := json.Unmarshal(b, &v); err != nil {
return err
}
switch value := v.(type) {
case float64:
*d = Duration(time.Duration(value))
return nil
case string:
tmp, err := time.ParseDuration(value)
if err != nil {
return err
}
*d = Duration(tmp)
return nil
default:
return errors.New("invalid duration")
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.