Quick note on this. JSON will add extra wrapping "
quotes to strings which can really mess with you.
How to catch and remove the extra wrapping "
's:
// UnmarshalJSON scrubs out whitespace from a valid json string, if any.
func (ss *ScrubString) UnmarshalJSON(data []byte) error {
ns := string(data)
// Check if we don't have a blank "\"\"" string.
if len(ns) > 2 && ns[0] != '"' && ns[len(ns)] != '"' {
*ss = ""
return nil
}
// Remove the extra quotes.
ns, err := strconv.Unquote(ns)
if err != nil {
return err
}
// Remove left/right whitespace.
*ss = ScrubString(strings.TrimSpace(ns))
return nil
}
package main
import (
"encoding/json"
"fmt"
"time"
)
// Company struct
type Company struct {
CompanyName string `json:"company_name"`
ID int `json:"id"`
}
type MyTime struct {
time.Time
}
func (m *MyTime) UnmarshalJSON(b []byte) error {
// Ignore null, like in the main JSON package.
if string(b) == "null" {
return nil
}
// Fractional seconds are handled implicitly by Parse.
var err error
m.Time, err = time.Parse(`"2006-01-02T15:04:05.000-0700"`, string(b))
return err
}
// ContactPointer struct
type ContactPointer struct {
Company *Company `json:"company,omitempty"`
DateCreated MyTime `json:"date_created"`
}
func main() {
contactResponseWV := []byte(`{"date_created": "2019-12-18T01:23:35.000+0000", "company":null}`)
// With Value
wv := ContactPointer{}
if err := json.Unmarshal(contactResponseWV, &wv); err != nil {
panic(err)
}
fmt.Printf("DateCreated: %+v", wv.DateCreated)
}
Add custom type, with extra formatting.
package main
import (
"encoding/json"
"fmt"
"time"
)
// Company struct
type Company struct {
CompanyName string `json:"company_name"`
ID int `json:"id"`
}
type JSONTime struct {
time.Time
format string
}
func NewJSONTime(format string) JSONTime {
return JSONTime{
format: format,
}
}
func (j *JSONTime) UnmarshalJSON(b []byte) error {
// Ignore null, like in the main JSON package.
if string(b) == "null" {
return nil
}
// Fractional seconds are handled implicitly by Parse.
var err error
if j.format == "" {
j.format = time.RFC3339
}
j.Time, err = time.Parse(`"`+j.format+`"`, string(b))
return err
}
// ContactPointer struct
type ContactPointer struct {
Company *Company `json:"company,omitempty"`
// TODO: get time.Time to work... but how to convert the JSON string to time?
DateCreated JSONTime `json:"date_created"`
//DateCreated string `json:"date_created"`
}
func main() {
contactResponseWV := []byte(`{"date_created": "2019-12-18T01:23:35.000+0000", "company":null}`)
// With Value
wv := ContactPointer{
DateCreated: NewJSONTime("2006-01-02T15:04:05.000-0700"),
}
if err := json.Unmarshal(contactResponseWV, &wv); err != nil {
panic(err)
}
fmt.Printf("DateCreated: %+v", wv.DateCreated)
}