如何使用Go解析此.Net JSON日期? 该值未分配。 它似乎解析了日期字段。
package main
import (
"encoding/json"
"fmt"
"time"
)
type MyStruct struct {
FirstField string
SomeTime time.Time
LastField string
}
type MyStructSlice struct {
MyStructs []MyStruct
}
func main() {
var s MyStructSlice
str := `{"MyStructs":[{"FirstField":"123", "SomeTime":"\/Date(1432187580000-0500)\/", "LastField":"456"}]}`
json.Unmarshal([]byte(str), &s)
fmt.Println(s)
}
答案 0 :(得分:1)
我将提供一些建议。你必须自己编写代码;)
首先,是否可以更改生成此JSON的.NET应用程序以生成更易解析的内容?如果你以RFC3339格式输出日期时间(类似1990-12-31T15:59:12-08:00)那么go会自动将它转换为time.Time实例,感谢http://golang.org/pkg/time/#Time.UnmarshalJSON
如果您无法更改客户端,则必须自行解析此日期:
从字符串中提取时间部分(1432187580000)。这看起来像UNIX纪元以来的毫秒数(ms)。您可以使用time.Unix(sec,nsec)将其转换为time.Time实例。
(可选)。在最后一步中创建的时间已经准确地表示了一个时间点。但是,如果您要将原始时区添加到其中(例如打印它),您需要:
答案 1 :(得分:0)
由于多种原因,该值未分配。首先,你的MyStruct看起来不对劲。您的JSON具有success = s.verify(signature);
密钥作为父密钥,其中包含一组对象。
但是你的结构由于某种原因甚至不像这个。至少必须有data
作为字段。所以让你的结构看起来像你正在接收的json。
另一件事是你的Date
将无法在正常日期解析此字符串:time.Time
。
P.S。现在您已经将结构更新为正常方式,您必须找到一种方法将您的奇怪刺痛解析为日期。如果您对.net应用程序有权限,我宁愿建议将json更改为正常时间戳或可以轻松解析的内容。
如果没有,则必须将Date(1432187580000-0500)
更改为SomeTime time.Time
,然后将字符串解析为正常时间戳,然后将此时间戳解析为日期。
答案 2 :(得分:0)
首先,您的模型是错误的,它不会对您的JSON中的数据结构进行建模。它应该是:
type Data struct {
Data []MyStruct `json:"data`
}
type MyStruct struct {
SomeTime string
}
适用于此,请在Go Playground上尝试。
问题是我们仍然有时间string
。
现在,如果您希望SomeTime
为time.Time
,则需要自行解析,您可以通过实施json.Unmarshaler
来实现:
type Data struct {
Data []MyStruct `json:"data`
}
type MyStruct struct {
SomeTime time.Time
}
func (m *MyStruct) UnmarshalJSON(data []byte) error {
// First unmashal it into a string:
ms := struct{ SomeTime string }{}
if err := json.Unmarshal(data, &ms); err != nil {
return err
}
s := ms.SomeTime
// s is of format: "/Date(1432187580000-0500)/"
// extract millis and time zone offset hours
i1 := strings.Index(s, "(")
i3 := strings.Index(s, ")")
i2 := strings.Index(s, "-")
if i2 < 0 {
i2 = strings.Index(s, "+")
}
if i1 < 0 || i2 < 0 || i3 < 0 {
return errors.New("Invalid format")
}
millis, err := strconv.ParseInt(s[i1+1:i2], 10, 64)
if err != nil {
return err
}
m.SomeTime = time.Unix(0, millis*1000000)
// Apply timezone:
zoneHours, err := strconv.ParseInt(s[i2:i3], 10, 64)
if err != nil {
return err
}
zone := time.FixedZone("something", int(zoneHours)*3600)
m.SomeTime = m.SomeTime.In(zone)
return nil
}
在Go Playground上尝试。