Home > Software engineering >  I can not parse date/time in Go - Gin
I can not parse date/time in Go - Gin

Time:07-28

I am sending this json:

{"origin":{"lat":23.589367061768648,"lng":58.42860314995051},"destination":null,"vehicle":"WATER_TANKER_600GL","scheduled_time":"2022-07-27T14:16:00Z04:00"}

Golang Gin handler function:

func (config *Config) CreateOrder(c *gin.Context) {

    userID := auth.GetToken(c).ID()

    data := &struct {
        Origin        models.Origin       `json:"origin" binding:"required"`
        Vehicle       VehicleType         `json:"vehicle" binding:"required"`
        Destination   *models.Destination `json:"destination" `
        ScheduledTime *time.Time          `json:"scheduled_time"`
    }{}

    if err := c.ShouldBindWith(data, binding.JSON); err != nil {
        fmt.Println(err) // -> prints the below error
        res.UnprocessableEntity(c, fmt.Sprintf("%s", err))
        return
    }

// rest of the code
}

I get this error:

parsing time "\"2022-07-27T14:16:00Z04:00\"" as "\"2006-01-02T15:04:05Z07:00\"": cannot parse "04:00\"" as "\""

CodePudding user response:

Note that JSON does not define a date or timestamp data type. Transferring a timestamp as a JSON string is possible, but how that timestamp string is interpreted–or should be interpreted–is not written in stone. The standard lib (the encoding/json package) supports unmarshaling time.Time values from JSON strings, but it does so by requiring them to adhere the RFC 3339 standard, else the unmarshaling will fail.

time.Time implements json.Unmarshaler, and Time.UnmarshalJSON() states that the JSON string must be in RFC 3339 layout which is:

RFC3339 = "2006-01-02T15:04:05Z07:00"

The Z in the layout means:

Numeric time zone offsets format as follows:

"-0700"  ±hhmm
"-07:00" ±hh:mm
"-07"    ±hh

Replacing the sign in the format with a Z triggers the ISO 8601 behavior of printing Z instead of an offset for the UTC zone. Thus:

"Z0700"  Z or ±hhmm
"Z07:00" Z or ±hh:mm
"Z07"    Z or ±hh

Which means if the time has UTC offset, it should be

"2022-07-27T14:16:00Z"

If the time has 04:00 zone, it should be

"2022-07-27T14:16:00 04:00"

The input "2022-07-27T14:16:00Z04:00" is invalid for RFC 3339. Either change your source to provide RFC 3339 compliant timestamp strings, or if you can't or don't want to, you may create your custom type that implements json.Unmarshaler, and you handle this non-RFC 3339 format yourself.

  • Related