0

I have a struct that I can't change and an array of these structs in a separate JSON file. I could have parsed data from JSON file easily, but there are mismatched types in same fields:

(main.go)

import "time"

type SomeType struct { 
    name string    `json: "name"`
    time time.Time `json: "someTime"`
}

(someData.json)

[
    {
        "name": "some name",
        "someTime": "15:20:00"
    },

    {
        "name": "some other name",
        "someTime": "23:15:00"
    }
]

If "time" field was a type of a string, I would simply use json.Unmarshal and parse all of the data from json into []SomeType, but since types mismatch, I can't find a way to do it correctly.

2 Answers 2

2

You should add the UnmarshalJSON method to your struct

type SomeType struct {
    Name string    `json:"name"`
    Time time.Time `json:"someTime"`
}

func (st *SomeType) UnmarshalJSON(data []byte) error {
    type parseType struct {
        Name string `json:"name"`
        Time string `json:"someTime"`
    }
    var res parseType
    if err := json.Unmarshal(data, &res); err != nil {
        return err
    }

    parsed, err := time.Parse("15:04:05", res.Time)
    if err != nil {
        return err
    }

    now := time.Now()
    st.Name = res.Name
    st.Time = time.Date(now.Year(), now.Month(), now.Day(), parsed.Hour(), parsed.Minute(), parsed.Second(), 0, now.Location())
    return nil
}

GoPlay

Sign up to request clarification or add additional context in comments.

Comments

1

I think you should define a custom time type, with a custom unmarshaller as follows:

type CustomTime struct {
        time.Time
}

func (t *CustomTime) UnmarshalJSON(b []byte) error {
        formattedTime, err := time.Parse(`"15:04:05"`, string(b))
        t.Time = formattedTime
        return err
}

And have another struct, which is basically the exact struct you have, instead it uses your custom time type rather than the original struct which uses time.Time:

type SameTypeWithDifferentTime struct {
        Name          string       `json:"name"`
        SomeTime      CustomTime   `json:"someTime"`
}

func (s SameTypeWithDifferentTime) ToOriginal() SomeType {
        return SomeType {
                Name: s.Name,
                SomeTime: s.SomeTime.Time,
        }
}

The rest of the process is pretty straight forward, you just deserialize your json to the new type, and use ToOriginal() receiver function to convert it to your original struct. Another point to mention here is that your not exporting your struct fields.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.