解组时日期为零 JSON
Zero date while unmarshaling JSON
我正在尝试用时间值解组 JSON。我有这个 JSON 结构。
{
"Nick": "cub",
"Email": "cub875@rambler.ru",
"Created_at": "2017-10-09",
"Subscribers": [
{
"Email": "rat1011@rambler.ru",
"Created_at": "2017-11-30"
},
{
"Email": "hound939@rambler.ru",
"Created_at": "2016-07-15"
},
{
"Email": "worm542@rambler.ru",
"Created_at": "2017-02-16"
},
{
"Email": "molly1122@rambler.ru",
"Created_at": "2016-11-30"
},
{
"Email": "goat1900@yandex.ru",
"Created_at": "2018-07-10"
},
{
"Email": "duck1146@rambler.ru",
"Created_at": "2017-09-04"
},
{
"Email": "eagle1550@mail.ru",
"Created_at": "2018-01-03"
},
{
"Email": "prawn1755@rambler.ru",
"Created_at": "2018-04-20"
},
{
"Email": "platypus64@yandex.ru",
"Created_at": "2018-02-17"
}
]
}
以及实现从JSON文件中读取结构User的函数。一切都很好,但是当我将 User 结构中的 CreatedAt 字段设置为 time.Time 类型时,我得到 0001-01-01 00:00:00 +0000 UTC 值 JSON 文件中每个字段的类型格式。
type Subscriber struct {
Email string `json: "Email"`
CreatedAt time.Time `json: "Created_at"`
}
type User struct {
Nick string `json: "Nick"`
Email string `json: "Email"`
CreatedAt string `json: "Created_at"`
Subscribers []Subscriber `json: "Subscribers"`
}
func main() {
// Slice where objects from users.json will be pushed
var jsonData []User
// ReadJSON and push User struct to jsonData slice
readJSON("users.json", &jsonData)
for _, user := range jsonData {
fmt.Println(user.Nick, user.Email, user.CreatedAt) // 0001-01-01 00:00:00 +0000 UTC
fmt.Println(user.Subscribers)
}
}
func readJSON(fileName string, userSlice *[]User) {
file, err := os.Open(fileName)
if err != nil {
log.Fatal(err)
}
bytes, err := ioutil.ReadAll(file)
if err != nil {
log.Fatal(err)
}
err1 := json.Unmarshal(bytes, &userSlice)
if err1 != nil {
log.Fatal(err1)
}
}
以 RFC3339 格式从 JSON 文件向用户读取时间的合适方法是什么?
您可以使用实现 json.Unmarshaler 接口的自定义时间类型。
您可以从这个结构开始:
type CustomTime struct {
time.Time // Embed time.Time to allow calling of normal time.Time methods
}
然后添加需要的UnmarshalJSON([]byte) error
函数。它可能看起来像这样:
func (c *CustomTime) UnmarshalJSON(b []byte) error {
if len(b) < 3 {
// Empty string: ""
return fmt.Errorf("Empty time value")
}
t, err := time.Parse("2006-01-02", string(b[1:len(b)-1])) // b[1:len(b)-1] removes the first and last character, as they are quotes
if err != nil {
return err
}
c.Time = t
return nil
}
您可以尝试 Go Playground
上的示例
我正在尝试用时间值解组 JSON。我有这个 JSON 结构。
{
"Nick": "cub",
"Email": "cub875@rambler.ru",
"Created_at": "2017-10-09",
"Subscribers": [
{
"Email": "rat1011@rambler.ru",
"Created_at": "2017-11-30"
},
{
"Email": "hound939@rambler.ru",
"Created_at": "2016-07-15"
},
{
"Email": "worm542@rambler.ru",
"Created_at": "2017-02-16"
},
{
"Email": "molly1122@rambler.ru",
"Created_at": "2016-11-30"
},
{
"Email": "goat1900@yandex.ru",
"Created_at": "2018-07-10"
},
{
"Email": "duck1146@rambler.ru",
"Created_at": "2017-09-04"
},
{
"Email": "eagle1550@mail.ru",
"Created_at": "2018-01-03"
},
{
"Email": "prawn1755@rambler.ru",
"Created_at": "2018-04-20"
},
{
"Email": "platypus64@yandex.ru",
"Created_at": "2018-02-17"
}
]
}
以及实现从JSON文件中读取结构User的函数。一切都很好,但是当我将 User 结构中的 CreatedAt 字段设置为 time.Time 类型时,我得到 0001-01-01 00:00:00 +0000 UTC 值 JSON 文件中每个字段的类型格式。
type Subscriber struct {
Email string `json: "Email"`
CreatedAt time.Time `json: "Created_at"`
}
type User struct {
Nick string `json: "Nick"`
Email string `json: "Email"`
CreatedAt string `json: "Created_at"`
Subscribers []Subscriber `json: "Subscribers"`
}
func main() {
// Slice where objects from users.json will be pushed
var jsonData []User
// ReadJSON and push User struct to jsonData slice
readJSON("users.json", &jsonData)
for _, user := range jsonData {
fmt.Println(user.Nick, user.Email, user.CreatedAt) // 0001-01-01 00:00:00 +0000 UTC
fmt.Println(user.Subscribers)
}
}
func readJSON(fileName string, userSlice *[]User) {
file, err := os.Open(fileName)
if err != nil {
log.Fatal(err)
}
bytes, err := ioutil.ReadAll(file)
if err != nil {
log.Fatal(err)
}
err1 := json.Unmarshal(bytes, &userSlice)
if err1 != nil {
log.Fatal(err1)
}
}
以 RFC3339 格式从 JSON 文件向用户读取时间的合适方法是什么?
您可以使用实现 json.Unmarshaler 接口的自定义时间类型。
您可以从这个结构开始:
type CustomTime struct {
time.Time // Embed time.Time to allow calling of normal time.Time methods
}
然后添加需要的UnmarshalJSON([]byte) error
函数。它可能看起来像这样:
func (c *CustomTime) UnmarshalJSON(b []byte) error {
if len(b) < 3 {
// Empty string: ""
return fmt.Errorf("Empty time value")
}
t, err := time.Parse("2006-01-02", string(b[1:len(b)-1])) // b[1:len(b)-1] removes the first and last character, as they are quotes
if err != nil {
return err
}
c.Time = t
return nil
}
您可以尝试 Go Playground
上的示例