【问题标题】:How to deal with date fields from JSON in a GO struct如何在 GO 结构中处理来自 JSON 的日期字段
【发布时间】: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 类型来解组。有了它,您可以以任何格式导出时间:仅日期;仅时间等。

标签: json go struct unmarshalling


【解决方案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 本身中提供所需的输出。
  • 为什么不两者都做呢?保留信息并以任何格式呈现。
猜你喜欢
  • 2014-10-14
  • 2013-02-18
  • 2017-04-24
  • 2023-03-27
  • 1970-01-01
  • 2021-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多