我正在尝试将一些json解组到结构中,出现以下内容:
package main
import (
"encoding/json"
"fmt"
"strings"
"time"
)
type Added struct {
Added *time.Time `json:"added"`
}
func main() {
st := strings.NewReader(`{"added": ""}`)
a := &Added{}
err := json.NewDecoder(st).Decode(&a)
if err != nil {
panic(err)
}
fmt.Println(a)
}
运行以上结果将导致:
panic: parsing time """" as ""2006-01-02T15:04:05Z07:00"": cannot parse """ as "2006"
于是我尝试一个自定义编组器:
package main
import (
"encoding/json"
"fmt"
"strings"
"time"
)
type Added struct {
Added *MyTime `json:"added"`
}
func main() {
st := strings.NewReader(`{"added": ""}`)
a := &Added{}
err := json.NewDecoder(st).Decode(&a)
if err != nil {
panic(err)
}
fmt.Println(a)
}
type MyTime struct {
*time.Time
}
func (m *MyTime) UnmarshalJSON(data []byte) error {
// Ignore null, like in the main JSON package.
if string(data) == "null" || string(data) == `""` {
return nil
}
// Fractional seconds are handled implicitly by Parse.
tt, err := time.Parse(`"`+time.RFC3339+`"`, string(data))
*m = MyTime{&tt}
return err
}
然后我得到:
&{%!v(PANIC=runtime error: invalid memory address or nil pointer dereference)}
那现在我该怎么办? 我只想处理json中的“”值.
并能够找到带有完整示例的游乐场。
import "time"
A Time represents an instant in time with nanosecond precision.
Programs using times should typically store and pass them as values, not pointers. That is, time variables and struct fields should be of type time.Time, not *time.Time.
I just kept fixing likely problems, for example, time.Time
, not *time.Time
, a real date, and so on, until I got a reasonable result:
package main
import (
"encoding/json"
"fmt"
"strings"
"time"
)
type MyTime struct {
time.Time
}
func (m *MyTime) UnmarshalJSON(data []byte) error {
// Ignore null, like in the main JSON package.
if string(data) == "null" || string(data) == `""` {
return nil
}
// Fractional seconds are handled implicitly by Parse.
tt, err := time.Parse(`"`+time.RFC3339+`"`, string(data))
*m = MyTime{tt}
return err
}
type Added struct {
Added MyTime `json:"added"`
}
func main() {
st := strings.NewReader(`{"added": "2012-04-23T18:25:43.511Z"}`)
var a Added
err := json.NewDecoder(st).Decode(&a)
if err != nil {
panic(err)
}
fmt.Println(a)
}
Playground: https://play.golang.org/p/Uusdp3DkXDU
Output:
{2012-04-23 18:25:43.511 +0000 UTC}
With an empty (""
) date string, the time.Time
zero value, 0001-01-01 00:00:00 +0000 UTC
:
Playground: https://play.golang.org/p/eQoEyqBlhg2
Output:
{0001-01-01 00:00:00 +0000 UTC}
Use the time
IsZero
method to test for the zero value.
func (t Time) IsZero() bool
IsZero reports whether t represents the zero time instant, January 1, year 1, 00:00:00 UTC.
I think you were very close to the solution with your custom marshaller. Maybe just revert to normal decoding for normal dates. This may help:
type MyTime time.Time
func (m *MyTime) UnmarshalJSON(data []byte) error {
// Ignore null, like in the main JSON package.
if string(data) == "null" || string(data) == `""` {
return nil
}
return json.Unmarshal(data, (*time.Time)(m))
}