How to decode Flutter iso8601 DateTime to Go Api RFC3339 pgtype.Date and pgtype.Timestamptz

huangapple go评论88阅读模式
英文:

How to decode Flutter iso8601 DateTime to Go Api RFC3339 pgtype.Date and pgtype.Timestamptz

问题

在我的Go API中,我试图使用json解码来解析以下json数据。

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

我遇到了一个错误:

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

我该如何修复这个错误?

这是我的结构体:

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

这是我的代码:

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

    var contract Contract

    decoder := json.NewDecoder(r.Body)

    err = decoder.Decode(&contract)
英文:

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)

答案1

得分: 3

Go使用RFC 3339来编码时间,如果你控制生成的JSON,只需要将2022-04-03T00:00:00.000改为2022-04-03T00:00:00.000Z

例如,这样可以工作。

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

如果你无法控制JSON,你需要编写一个自定义的解组方法

英文:

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.

答案2

得分: 0

这是我最终在Flutter中使用pgtype.Datepgtype.DateTimestamptz在我的Go API和PostgreSQL中的列类型DATEDATETIME实现的解决方案。我无法在这种数据类型中使用指针。

首先,我在Flutter中创建了一个辅助函数,如下所示:

import 'package:intl/date_symbol_data_local.dart';
import 'package:intl/intl.dart';

extension DateTimeExtension on DateTime {
  String format([String pattern = 'dd/MM/yyyy', String? locale]) {
    if (locale != null && locale.isNotEmpty) {
      initializeDateFormatting(locale);
    }
    return DateFormat(pattern, locale).format(this);
  }

  String formatDbDateTime(
      [String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", String? locale]) {
    if (locale != null && locale.isNotEmpty) {
      initializeDateFormatting(locale);
    }
    return DateFormat(pattern, locale).format(this);
  }

  String formatDbDate([String pattern = 'yyyy-MM-dd', String? locale]) {
    if (locale != null && locale.isNotEmpty) {
      initializeDateFormatting(locale);
    }
    return DateFormat(pattern, locale).format(this);
  }

  String formatLocalDate([String pattern = 'dd MMMM yyyy', String? locale]) {
    if (locale != null && locale.isNotEmpty) {
      initializeDateFormatting(locale);
    }
    return DateFormat(pattern, locale).format(this);
  }

  String formatLocalDateTime(
      [String pattern = 'dd MMMM yyyy h:mm a', String? locale]) {
    if (locale != null && locale.isNotEmpty) {
      initializeDateFormatting(locale);
    }
    return DateFormat(pattern, locale).format(this);
  }
}

我在Flutter模型中使用它来格式化日期,用于我的Go API:

if (planAcceptedDate != null) {
  data['plan_accepted_date'] = planAcceptedDate!.formatDbDateTime();
} else {
  data['plan_accepted_date'] = null;
}

if (invoiceDate != null) {
  data['invoice_date'] = invoiceDate!.formatDbDate();
} else {
  data['invoice_date'] = null;
}

在我的Flutter视图表单中,我像这样使用它:

Container(
  padding: EdgeInsets.all(8.0),
  child: Text(
    _matter.planAcceptedDate == null
        ? ''
        : _matter.planAcceptedDate!.formatLocalDateTime(),
    style: TextStyle(
      color: appTextColor,
      fontWeight: FontWeight.normal,
      fontSize: _user.fontsize,
    ),
  ),
),
Container(
  padding: EdgeInsets.all(8.0),
  child: Text(
    _matter.invoiceDate == null
        ? ''
        : _matter.invoiceDate!.formatLocalDate(),
    style: TextStyle(
      color: appTextColor,
      fontWeight: FontWeight.normal,
      fontSize: _user.fontsize,
    ),
  ),
),

我的Go结构体如下所示:

PlanAcceptedDate pgtype.Timestamptz `json:"plan_accepted_date"`
InvoiceDate      pgtype.Date        `json:"invoice_date"`
英文:

This is the solution I finally implemented in Flutter using pgtype.Date and pgtype.DateTimestamptz in my Go api and column types DATE and DATETIME in Postgresql. I was unable to use a pointer with this data type.

First I created a helper in Flutter like this:

import 'package:intl/date_symbol_data_local.dart';
import 'package:intl/intl.dart';

extension DateTimeExtension on DateTime {
  String format([String pattern = 'dd/MM/yyyy', String? locale]) {
    if (locale != null && locale.isNotEmpty) {
      initializeDateFormatting(locale);
    }
    return DateFormat(pattern, locale).format(this);
  }

  String formatDbDateTime(
      [String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", String? locale]) {
    if (locale != null && locale.isNotEmpty) {
      initializeDateFormatting(locale);
    }
    return DateFormat(pattern, locale).format(this);
  }

  String formatDbDate([String pattern = 'yyyy-MM-dd', String? locale]) {
    if (locale != null && locale.isNotEmpty) {
      initializeDateFormatting(locale);
    }
    return DateFormat(pattern, locale).format(this);
  }

  String formatLocalDate([String pattern = 'dd MMMM yyyy', String? locale]) {
    if (locale != null && locale.isNotEmpty) {
      initializeDateFormatting(locale);
    }
    return DateFormat(pattern, locale).format(this);
  }

  String formatLocalDateTime(
      [String pattern = 'dd MMMM yyyy h:mm a', String? locale]) {
    if (locale != null && locale.isNotEmpty) {
      initializeDateFormatting(locale);
    }
    return DateFormat(pattern, locale).format(this);
  }
}

I used this in my Flutter models to format the date for my Go Api:

if (planAcceptedDate != null) {
  data['plan_accepted_date'] = planAcceptedDate!.formatDbDateTime();
} else {
  data['plan_accepted_date'] = null;
}

if (invoiceDate != null) {
  data['invoice_date'] = invoiceDate!.formatDbDate();
} else {
  data['invoice_date'] = null;
}

and in my Flutter view form I use it like this:

        Container(
          padding: EdgeInsets.all(8.0),
          child: Text(
            _matter.planAcceptedDate == null
                ? ''
                : _matter.planAcceptedDate!.formatLocalDateTime(),
            style: TextStyle(
              color: appTextColor,
              fontWeight: FontWeight.normal,
              fontSize: _user.fontsize,
            ),
          ),
        ),
        Container(
          padding: EdgeInsets.all(8.0),
          child: Text(
            _matter.invoiceDate == null
                ? ''
                : _matter.invoiceDate!.formatLocalDate(),
            style: TextStyle(
              color: appTextColor,
              fontWeight: FontWeight.normal,
              fontSize: _user.fontsize,
            ),
          ),
        ),

My Go struct looks like this:

PlanAcceptedDate pgtype.Timestamptz `json:"plan_accepted_date"`
InvoiceDate      pgtype.Date        `json:"invoice_date"`

huangapple
  • 本文由 发表于 2022年4月3日 12:35:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/71723032.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定