Parsing odd JSON date formats in Go

I am calling old api and returning objects on form.

{ value: 1, time: "/Date(1412321990000)/" }

      

Using a structure defined with

type Values struct{
  Value int
  Time time.Time
}

      

Gives me time & ParseError. I'm new to Go, is there a way to define how this should be serialized / deserialized ?. Ultimately I want it to be like time. Temporary object.

This date format is also an older .NET format. It is also not possible to modify the output file.

+3


source to share


2 answers


You need to implement json Unmarshaler interface in your value structure.

// UnmarshalJSON implements json Unmarshaler interface
func (v *Values) UnmarshalJSON(data []byte) error {
    // create tmp struct to unmarshal into
    var tmp struct {
        Value int    `json:"value"`
        Time  string `json:"time"`
    }
    if err := json.Unmarshal(data, &tmp); err != nil {
        return err
    }

    v.Value = tmp.Value

    // trim out the timestamp
    s := strings.TrimSuffix(strings.TrimPrefix(tmp.Time, "/Date("), ")/")

    i, err := strconv.ParseInt(s, 10, 64)
    if err != nil {
        return err
    }

    // create and assign time using the timestamp
    v.Time = time.Unix(i/1000, 0)

    return nil
}

      



Check out this working example .

+5


source


Another approach is to define a custom type for time instead of manually creating the temp structure.

Also the implementation time. Time makes it easier to access all the functions defined on it, for example .String()

.



type WeirdTime struct{ time.Time }

type Value struct {
    Value int
    Time  WeirdTime
}

func (wt *WeirdTime) UnmarshalJSON(data []byte) error {
    if len(data) < 9 || data[6] != '(' || data[len(data)-3] != ')' {
        return fmt.Errorf("unexpected input %q", data)
    }
    t, err := strconv.ParseInt(string(data[7:len(data)-3]), 10, 64)
    if err != nil {
        return err
    }
    wt.Time = time.Unix(t/1000, 0)
    return nil
}

      

playground

+1


source







All Articles