Given
type NullTime struct {
Time time.Time
Valid bool // Valid is true if Time is not NULL
}
and
type PayinCount struct {
DateShiftStart sql.NullTime `json:"dateShiftStart"`
DateShiftEnd sql.NullTime `json:"dateShiftend"`
}
when I process the following JSON
{
"dateShiftStart":"2023-10-16",
"dateShiftEnd":"2023-10-23"
}
with
var payinsCount PayinsCount
err = json.Unmarshal(body, &payinsCount)
if err != nil {
sendErrorResponse(w, err.Error(), http.StatusBadRequest)
return
}
where sendErrorResponse is the following helper process
func sendErrorResponse(w http.ResponseWriter, err string, statusCode int) {
messageStatusCode := MessageStatusCode{
Message: err,
StatusCode: statusCode}
w.WriteHeader(statusCode)
json.NewEncoder(w).Encode(messageStatusCode)
}
I get the following message
{
"message": "json: cannot unmarshal string into Go struct field PayinsCount.dateShiftStart of type sql.NullTime",
"statusCode": 400
}
How do I resolve this issue?
I ended up using the following. I added the following type.
type NullDate sql.NullTime
then I changed PayinsCount to use NullDate
type PayinsCount struct {
DateShiftStart NullDate `json:"dateShiftStart,omitempty"`
DateShiftEnd NullDate `json:"dateShiftend,omitempty"`
}
then I created
// UnmarshalJSON for NullDate
func (nd *NullDate) UnmarshalJSON(b []byte) error {
s := string(b)
s = strings.ReplaceAll(s, "\"", "")
x, err := time.Parse(time.DateOnly, s)
if err != nil {
nd.Valid = false
return err
}
nd.Time = x
nd.Valid = true
return nil
}
now when I process the following JSON
{
"dateShiftStart":"2023-10-16",
"dateShiftEnd":"2023-10-23"
}
with
var payinsCount PayinsCount
err = json.Unmarshal(body, &payinsCount)
if err != nil {
sendErrorResponse(w, err.Error(), http.StatusBadRequest)
return
}
it works. I end up with a valid PayinsCount instance.
For completeness here is the MarshalJSON function for NullDate
// MarshalJSON for NullDate
func (nd NullDate) MarshalJSON() ([]byte, error) {
if !nd.Valid {
return []byte("null"), nil
}
val := fmt.Sprintf("\"%s\"", nd.Time.Format(time.DateOnly))
return []byte(val), nil
}
Note the escaped double quotes - without them the encoding/json marshalling code was processing the date string in 3 chunks and I was getting the following error
error(*encoding/json.SyntaxError) *{msg: "invalid character '-' after top-level value", Offset: 0}