Home > Software design >  Error decoding date from Flutter iso8601 to Go api RFC3339
Error decoding date from Flutter iso8601 to Go api RFC3339

Time:04-03

In my Go API I'm trying to use json decode to parse the following json.

{"contract_id":0,"date_established":"2022-04-03T00:00:00.000","expiry_date":null,"extension_expiry_date":null,"description":"fffff"}

I get an error:

parsing time "\"2022-04-03T00:00:00.000\"" as "\"2006-01-02T15:04:05Z07:00\"": cannot parse "\"" as "Z07:00"

How can I fix this error?

This is my struct:

// Contract model
type Contract struct {
    ContractId          *int       `json:"contract_id"`
    CompanyId           *int       `json:"company_id"`
    DateEstablished     *time.Time `json:"date_established"`
    ExpiryDate          *time.Time `json:"expiry_date"`
    ExtensionExpiryDate *time.Time `json:"extension_expiry_date"`
    Description         *string    `json:"description"`
}

Here is my code:

func (rs *appResource) contractCreate(w http.ResponseWriter, r *http.Request) {

    var contract Contract

    decoder := json.NewDecoder(r.Body)

    err = decoder.Decode(&contract)

CodePudding user response:

Go uses RFC 3339 for encoding time, if you control the json being produced you just need to change 2022-04-03T00:00:00.000 to 2022-04-03T00:00:00.000Z.

For instance this works.

type Contract struct {
    ContractId          *int       `json:"contract_id"`
    CompanyId           *int       `json:"company_id"`
    DateEstablished     *time.Time `json:"date_established"`
    ExpiryDate          *time.Time `json:"expiry_date"`
    ExtensionExpiryDate *time.Time `json:"extension_expiry_date"`
    Description         *string    `json:"description"`
}

func main() {
    body := `{"contract_id":0,"date_established":"2022-04-03T00:00:00.000Z","expiry_date":null,"extension_expiry_date":null,"description":"fffff"}`

    var contract Contract
    reader := strings.NewReader(body)
    decoder := json.NewDecoder(reader)
    err := decoder.Decode(&contract)
    if err != nil {
        fmt.Println("Error: ", err)
    } else {
        fmt.Printf("Contract: % v\n", contract)
    }
}

If you don't control the json, you need to write a custom unmarshal method.

CodePudding user response:

This is the solution I finally implemented in Flutter using pgtype.Date in my Go api and column type DATE in Postgresql. I was unable to use a pointer with this data type. The date string then becomes 2006-01-02.

in Flutter:

Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = {};
    data['contract_id'] = contractId;
    if (dateEstablished != null) {
      data['date_established'] =
          DateFormat("yyyy-MM-dd").format(dateEstablished!);
    } else {
      data['date_established'] = null;
    }
    if (expiryDate != null) {
      data['expiry_date'] = DateFormat("yyyy-MM-dd").format(expiryDate!);
    } else {
      data['expiry_date'] = null;
    }
    if (extensionExpiryDate != null) {
      data['extension_expiry_date'] =
          DateFormat("yyyy-MM-dd").format(extensionExpiryDate!);
    } else {
      data['extension_expiry_date'] = null;
    }
    data['description'] = description;
    return data;
  }

in my go api:

// Contract model
type Contract struct {
    ContractId          *int        `json:"contract_id"`
    DateEstablished     pgtype.Date `json:"date_established"`
    ExpiryDate          pgtype.Date `json:"expiry_date"`
    ExtensionExpiryDate pgtype.Date `json:"extension_expiry_date"`
    Description         *string     `json:"description"`
}
  • Related