Home > database >  hh:mm:ss to time.Time while parsing from JSON in Go
hh:mm:ss to time.Time while parsing from JSON in Go

Time:07-30

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.

CodePudding user response:

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.

CodePudding user response:

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

  • Related