英文:
Parsing odd JSON date formats in Go
问题
我正在调用一个旧的 API,它返回的对象形式如下:
{ value: 1, time: "/Date(1412321990000)/" }
我使用以下定义的结构体:
type Values struct{
Value int
Time time.Time
}
但是我得到了一个 &time.ParseError。作为 Go 的初学者,有没有办法让我定义如何序列化/反序列化这个对象?最终,我确实希望它作为一个 time.Time 对象。
这个日期格式似乎是一个较旧的 .NET 格式。我也无法更改输出。
英文:
I'm calling a older api, and its returning objects in the form of.
{ value: 1, time: "/Date(1412321990000)/" }
Using a struct defined with
type Values struct{
Value int
Time time.Time
}
Gives me a &time.ParseError. I'm a beginner at Go, is there a way for me to define how this should be serialized/deserialized?. Ultimately I do want it as a time.Time object.
This date format seems to be an older .NET format too. Can't really get the output changed either.
答案1
得分: 5
你需要在你的Values结构体上实现json的Unmarshaler接口。
// UnmarshalJSON 实现了json的Unmarshaler接口
func (v *Values) UnmarshalJSON(data []byte) error {
// 创建一个临时结构体进行解析
var tmp struct {
Value int `json:"value"`
Time string `json:"time"`
}
if err := json.Unmarshal(data, &tmp); err != nil {
return err
}
v.Value = tmp.Value
// 去除时间戳的前缀和后缀
s := strings.TrimSuffix(strings.TrimPrefix(tmp.Time, "/Date("), ")/")
i, err := strconv.ParseInt(s, 10, 64)
if err != nil {
return err
}
// 使用时间戳创建并赋值时间
v.Time = time.Unix(i/1000, 0)
return nil
}
可以查看这个可运行的示例。
英文:
You need to implement the json Unmarshaler interface on your Values struct.
// UnmarshalJSON implements json's Unmarshaler interface
func (v *Values) UnmarshalJSON(data []byte) error {
// create tmp struct to unmarshal into
var tmp struct {
Value int `json:"value"`
Time string `json:"time"`
}
if err := json.Unmarshal(data, &tmp); err != nil {
return err
}
v.Value = tmp.Value
// trim out the timestamp
s := strings.TrimSuffix(strings.TrimPrefix(tmp.Time, "/Date("), ")/")
i, err := strconv.ParseInt(s, 10, 64)
if err != nil {
return err
}
// create and assign time using the timestamp
v.Time = time.Unix(i/1000, 0)
return nil
}
Check out this working example.
答案2
得分: 1
另一种方法是定义一个自定义类型来表示时间,而不是手动创建一个临时结构体。
此外,嵌入time.Time类型可以更容易地访问其定义的所有函数,比如.String()
。
type WeirdTime struct{ time.Time }
type Value struct {
Value int
Time WeirdTime
}
func (wt *WeirdTime) UnmarshalJSON(data []byte) error {
if len(data) < 9 || data[6] != '(' || data[len(data)-3] != ')' {
return fmt.Errorf("unexpected input %q", data)
}
t, err := strconv.ParseInt(string(data[7:len(data)-3]), 10, 64)
if err != nil {
return err
}
wt.Time = time.Unix(t/1000, 0)
return nil
}
英文:
A different approach is to define a custom type for the time instead of manually creating a temp struct.
Also embedding time.Time makes it easier to access all the functions defined on it, like .String()
.
type WeirdTime struct{ time.Time }
type Value struct {
Value int
Time WeirdTime
}
func (wt *WeirdTime) UnmarshalJSON(data []byte) error {
if len(data) < 9 || data[6] != '(' || data[len(data)-3] != ')' {
return fmt.Errorf("unexpected input %q", data)
}
t, err := strconv.ParseInt(string(data[7:len(data)-3]), 10, 64)
if err != nil {
return err
}
wt.Time = time.Unix(t/1000, 0)
return nil
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论