Home  >  Article  >  Backend Development  >  Unmarshalling sql.NullTime structures in Go

Unmarshalling sql.NullTime structures in Go

PHPz
PHPzforward
2024-02-09 14:42:091184browse

在 Go 中解组 sql.NullTime 结构

php Editor Xiaoxin In the Go language, we often use the sql.NullTime structure to process the time field in the database. The NullTime structure can represent a nullable time value and is very suitable for handling null values ​​in the database. In this article, we will explain how to unmarshal a sql.NullTime structure and how to correctly handle null situations that may exist within it. Whether you are a beginner or an experienced developer, this article will provide you with clear guidance to help you better understand and use the NullTime structure.

Question content

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"
}

and

var payinsCount PayinsCount
err = json.Unmarshal(body, &payinsCount)
if err != nil {
    sendErrorResponse(w, err.Error(), http.StatusBadRequest)
    return
}

Where sendErrorResponse is the following auxiliary 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 received the following message

{
    "message": "json: cannot unmarshal string into Go struct field PayinsCount.dateShiftStart of type sql.NullTime",
    "statusCode": 400
}

how to solve this problem?

Workaround

I ended up using the following. I added the following types.

type NullDate sql.NullTime

Then I changed the 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"
}

and

var payinsCount PayinsCount
err = json.Unmarshal(body, &payinsCount)
if err != nil {
    sendErrorResponse(w, err.Error(), http.StatusBadRequest)
    return
}

It works. I ended 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 marshaling code processes the date string in 3 chunks and I get the following error

error(*encoding/json.SyntaxError) *{msg: "invalid character '-' after top-level value", Offset: 0}

The above is the detailed content of Unmarshalling sql.NullTime structures in Go. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete