2

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 "\""
2

1 Answer 1

3

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.

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

2 Comments

I would add a minor note that, strictly speaking, JSON does not have a data type for time instants, so the fact encoding/json is written to interpret strings being unmarshaled to variables of time.Time as formatted according to RFC3339 is an implementation detail which will be well hidden in the program. So if I were to code such a program I'd define my own logic to parse these time instants even if in the end it would call out to the standard library's implementation: just to make clear what the expectations are.
@kostix Thanks for the note, added it to the answer.

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.