如何在 GO 结构中处理来自 JSON 的日期字段

Posted

技术标签:

【中文标题】如何在 GO 结构中处理来自 JSON 的日期字段【英文标题】:How to deal with date fields from JSON in a GO struct 【发布时间】:2021-11-28 11:17:00 【问题描述】:

我有一个 JSON 内容,其中包含一些日期字段,如“resolutiondate”、“created”和“updated”,如下所示


   "expand":"names,schema",
   "startAt":0,
   "maxResults":50,
   "total":1,
   "issues":[
      
         "expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
         "id":"id",
         "self":"https://url1",
         "key":"key1",
         "fields":
            "summary":"Summary-1",
            "customfield_10406":null,
            "resolutiondate":"2021-06-10T10:07:35.000+0000",
            "created":"2021-06-10T10:05:24.000+0000",
            "description":"Description-1",
            ...
            ...
            ...

我正在将此 JSON 数据解组为 GO 结构并将数据保存在 Excel 表中。一切都按预期工作,唯一的问题是我在 GO 结构中将日期字段定义为字符串数据类型,如下所示:

        Resolved           string `json:"resolutiondate,omitempty"`
        Created            string `json:"created,omitempty"`

因此保存在 excel 文件中的最终数据如下所示:

但我想将它们保存为 Excel 工作表中的日期数据类型,采用用户定义的格式-mm/dd/yyyy。如何有效地使用 Golang 的 time 包来实现这一点?请帮忙。

注意:我将无法分享我的完整代码和完整的 JSON 文件。

【问题讨论】:

你试过什么?您的代码仅显示引入字符串,但您知道 time 包是您想要的。你自己试过吗?你能展示一下这段代码以及出了什么问题吗? 首先,您需要一个自定义的 time.Time 类型来解组。有了它,您可以以任何格式导出时间:仅日期;仅时间等。 【参考方案1】:

要从自定义格式解组,您需要创建 time.Time 包装器并实现 json.Unmarshaler 接口。

type CustomTime struct 
    time.Time


func (t *CustomTime) UnmarshalJSON(b []byte) (err error) 
    date, err := time.Parse(`"2006-01-02T15:04:05.000-0700"`, string(b))
    if err != nil 
        return err
    
    t.Time = date
    return

现在将您的时间字段指定为CustomTime

Resolved           CustomTime `json:"resolutiondate,omitempty"`
Created            CustomTime `json:"created,omitempty"`

要写入 excel,您需要提供有关您的实施的更多信息。

但示例解决方案:

func (t *CustomTime) ExcelDate() string 
    return t.Format("01/02/2006")

【讨论】:

不要费心从字节中删除" - 只需将引号直接放在格式字符串中,例如date, err := time.Parse(`"2006-01-02T15:04:05.000+0000"`, s) 这个格式化时间是mm/dd/yyyy布局吗? @nipuna,这解析时间。当你写出你想要格式化的excel文件时。实际上我认为整个日期会进入 excel 文件,并指示 excel 以 mm/dd/yyyy 布局显示这些日期。 以您喜欢的任何格式输出:v.Resolved.Time.Format("01/02/2006")v.Created.Time.Format(time.RFC3339) @colm.anseo 感谢您的指出。我将更新示例。【参考方案2】:

您可以做的是,将字符串包装为您自己的自定义类型,并使其实现Unmarshaler接口:

type Unmarshaler interface 
    UnmarshalJSON([]byte) error

然后花时间使用 JSON 并将其解析为 time.Time 并使用您的自定义布局格式化 mm/dd/yyyy

type Date string

func (d *Date) UnmarshalJSON(bytes []byte) error 
    dd, err := time.Parse(`"2006-01-02T15:04:05.000+0000"`, string(bytes))
    if err != nil
        return err
    
    *d = Date(dd.Format("01/02/2006"))

    return nil

现在你可以使用

Created            Date `json:"created,omitempty"`

在你的 Go 结构中并解组。

运行示例代码here

【讨论】:

通过将时间强制转换为仅包含日期信息的字符串,您会在此处丢失信息。最好解组为基于 time.Time 的类型 - 然后在事后以您想要的任何格式渲染 @colm.anseo 是的,正确的。但我专注于问题的期望,并在 Unmarshaler 本身中提供所需的输出。 为什么不两者都做呢?保留信息并以任何格式呈现。

以上是关于如何在 GO 结构中处理来自 JSON 的日期字段的主要内容,如果未能解决你的问题,请参考以下文章

Go语言处理JSon字段

Go 中使用 JSON 时,如何区分空字段和未设置字段

当 JSON 字段键是日期时,如何将 JSON 对象解组为 Golang 结构?

如何在 ReactJS 中循环来自外部文件的 JSON 数据?

Go,如何导入其他包的结构和字段?

Go语言JSON 处理