Home > OS >  Golang get datetime value with json unmarshall
Golang get datetime value with json unmarshall

Time:04-27

In my code,a method listen to a redis queue. I took the data sent by Redis as "payload" variable for following code example. "currenttime" variable is a time.time, but json.unmarshall change it as string value. How can I prevent this? I want to obtain a time.time data from currenttime. Also the "value" data changes dynamically. "count", "name" and "currenttime" variable names can be changed every time. I can just look at the values.

type Event struct {
    ID    string      `json:"id"`
    Value interface{} `json:"value"`
}

func main() {

    payload := "{\"id\":\"61e310f79b9a4db146a8cb7d\",\"value\":{\"Value\":{\"count\":55,\"currenttime\":\"2022-02-23T00:00:00Z\",\"name\":\"numberone\"}}}"
    var event Event
    if err := json.Unmarshal([]byte(payload), &event); err != nil {
        fmt.Println(err)
    }
    fmt.Println(event)
}

CodePudding user response:

If Event.Value.Value has a pre-defined structure

Use proper struct to model your input JSON, where you can use time.Time for the currenttime JSON property:

type Event struct {
    ID    string `json:"id"`
    Value struct {
        Value struct {
            Count       int       `json:"count"`
            CurrentTime time.Time `json:"currenttime"`
            Name        string    `json:"name"`
        } `json:"Value"`
    } `json:"value"`
}

Printing it like:

fmt.Println(event)
fmt.Printf("% v\n", event)
fmt.Printf("%T %v\n", event.Value.Value.CurrentTime, event.Value.Value.CurrentTime)

Output is (try it on the Go Playground):

{61e310f79b9a4db146a8cb7d {{55 2022-02-23 00:00:00  0000 UTC numberone}}}
{ID:61e310f79b9a4db146a8cb7d Value:{Value:{Count:55 CurrentTime:2022-02-23 00:00:00  0000 UTC Name:numberone}}}
time.Time 2022-02-23 00:00:00  0000 UTC

If Event.Value.Value has no pre-defined structure

If properties of Event.Value.Value can change dynamically, use a map (map[string]interface{}) to unmarshal into. Since we can't tell this time that we want a time.Time value (other properties do not hold time values), the time field will be unmarshaled into a string. So you have to iterate over its values and try to parse the values with the proper layout. If parsing it as a time succeeds, we have what we want.

Here's how it would look like:

type Event struct {
    ID    string `json:"id"`
    Value struct {
        Value map[string]interface{} `json:"Value"`
    } `json:"value"`
}

func main() {

    payload := "{\"id\":\"61e310f79b9a4db146a8cb7d\",\"value\":{\"Value\":{\"foo\":55,\"mytime\":\"2022-02-23T00:00:00Z\",\"bar\":\"numberone\"}}}"
    var event Event
    if err := json.Unmarshal([]byte(payload), &event); err != nil {
        fmt.Println(err)
    }

    for _, v := range event.Value.Value {
        if s, ok := v.(string); ok {
            t, err := time.Parse("2006-01-02T15:04:05Z", s)
            if err == nil {
                fmt.Println("Found time:", t)
            }
        }
    }
}

This will output (try it on the Go Playground):

Found time: 2022-02-23 00:00:00  0000 UTC
  • Related