【问题标题】:How to unmarshall time string into time.Time in golang?go - 如何在golang中将时间字符串解组为time.Time?
【发布时间】:2022-11-14 07:51:36
【问题描述】:

我正在使用 JOIN、CONCAT、GROUP_CONCAT、JSON_OBJECT 从多个表中读取数据。使用 gorm 将数据读入下面提到的模型。

type OrgUserDisPublisherData struct {
    Disciplines datatypes.JSON `json:"disciplines" example:"[]"`
    User        datatypes.JSON `json:"user"`
}

此过程已成功完成。但是当我尝试将 OrgUserDisPublisherData.Disciplines 解组为另一个具有 time.Time 数据类型的结构时。我收到以下错误 parsing time "\"2022-11-03 07:08:09.000000\"" as "\"2006-01-02T15:04:05Z07:00\"": cannot parse " 07:08:09.000000\"" as "T"

用于解组的最终模型

type Discipline struct {
        Name              string    `json:"name"`
        Code              string    `json:"code"`
        IsPrimary         uint      `json:"isPrimary"`
        IsAligned         uint      `json:"isAligned"`
        IsTrainingFaculty uint      `json:"isTrainingFaculty"`
        AlignmentDate     time.Time `json:"alignmentDate"`
        UnalignmentDate   time.Time `json:"UnalignmentDate"`
        ExpiryDate        time.Time `json:"expiryDate"`
        ExternalId        string    `json:"externalId"`
        Status            string    `json:"status"`
        CreatedAt         time.Time `json:"createdAt"`
        UpdatedAt         time.Time `json:"updatedAt"`
    }

同时,在向表中插入数据时,使用了相同的模型,并且不会引发任何与时间相关的错误。 我如何在解组时处理时间,而不管时间属性中存在的数据如何?

【问题讨论】:

  • 如果您的输入不符合 RFC-3339,您应该使用自定义编组器声明您自己的时间类型。这篇文章可能对你有所帮助:romangaranin.net/posts/2021-02-19-json-time-and-golang
  • 声明新类型的替代方法是确保查询创建的 JSON 对象中的时间戳值具有 time.TimeUnmarshalJSON 所期望的格式;这你可以用to_char 来做,例如to_char(created_at, 'YYYY-MM-DDTHH24:MI:SSTZH:TZM')

标签: json go go-gorm go-structtag


【解决方案1】:

这里的问题是 GoLang 结构中日期/时间类型的默认 JSON 编组行为是使用 ISO8601 格式的日期/时间字符串。

这由错误消息中的格式字符串标识,在日期和时间以及时区后缀之间带有T 分隔符。 Discipline JSON 字符串中的值不符合此格式,缺少 T 分隔符和任何时区。因此错误。

如果您可以影响 gorm 生成的 JSON 字符串的格式(我不熟悉,所以不能说您是否可以或如何这样做),那么最简单的解决方案是确保您的 JSON 字符串时间字段是格式为 ISO8601/RFC3339 字符串。

如果你无法控制它,那么你有两个选择:

  1. 通过中间 map[string]any 对 JSON 进行一些预处理并重新格式化相应的字段。如果gorm 格式至少是一致的,那么这可能就像在空间上拆分字符串一样简单,从时间中删除最后的 3dps,附加适当的时区(或者如果时间是 UTC,则只是 Z)然后重新- 使用T 分隔符组装。

  2. 使用具有json.Marshaller 实现的自定义时间类型,该实现与gorm 格式化值一起正常工作(您仍然需要知道哪个时区适用于持久值并在编组时正确应用)。

    这两者都容易受到日期/时间变量的 gorm 格式变化和误用的影响(在选项 #1 的情况下未能进行预处理,并且在选项的情况下错误地使用 time.Time 而不是自定义类型#2)。

    出于这个原因,如果可能的话,修改gorm 的格式化输出将是我的首选方法。

【讨论】:

    猜你喜欢
    • 2021-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-11
    • 2017-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多