使用Go

时间:2015-05-21 06:25:28

标签: json go

如何使用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)
}

Go Playground

3 个答案:

答案 0 :(得分:1)

我将提供一些建议。你必须自己编写代码;)

首先,是否可以更改生成此JSON的.NET应用程序以生成更易解析的内容?如果你以RFC3339格式输出日期时间(类似1990-12-31T15:59:12-08:00)那么go会自动将它转换为time.Time实例,感谢http://golang.org/pkg/time/#Time.UnmarshalJSON

如果您无法更改客户端,则必须自行解析此日期:

  1. 从字符串中提取时间部分(1432187580000)。这看起来像UNIX纪元以来的毫秒数(ms)。您可以使用time.Unix(sec,nsec)将其转换为time.Time实例。

  2. (可选)。在最后一步中创建的时间已经准确地表示了一个时间点。但是,如果您要将原始时区添加到其中(例如打印它),您需要:

  3. 示例:http://play.golang.org/p/Pkahyg2vZa

答案 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

现在,如果您希望SomeTimetime.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上尝试。