首页 > 解决方案 > 适用于 JSON Marshall 的多种自定义时间格式

问题描述

我有一个实用程序函数,用于编组和解组 go 中的自定义时间格式,该函数适用于一种格式字符串,并在 JSON 模型中使用如下

    type Entry struct {
        ID                int              `json:"id"`
        AuthorisedBy      string           `json:"authorisedBy"`
        Duid              string           `json:"duid"`
        IntervalCount     int32            `json:"intervalCount"`
        Intervals         []int32          `json:"intervals"`
        RequestId         string           `json:"requestId"`
        RequestTimestamp  time.Time        `json:"requestTimestamp"`
        TradingDate       utils.CustomTime `json:"tradingDate"`
        Unit              string           `json:"unit"`
        RebidExplanation  string           `json:"rebidexplanation"`
        AcceptedTimestamp time.Time        `json:"acceptedTimestamp"`
}

效用函数是。

package utils

import (
    "database/sql/driver"
    "fmt"
    "strings"
    "time"
)

type CustomTime struct {
    time.Time,
}

const ctLayout = "2006-01-02"

func (ct *CustomTime) UnmarshalJSON(b []byte) (err error) {
    s := strings.Trim(string(b), "\"")
    if s == "null" {
        ct.Time = time.Time{}
        return
    }
    ct.Time, err = time.Parse(ctLayout, s)
    return
}

func (ct *CustomTime) MarshalJSON() ([]byte, error) {
    if ct.Time.UnixNano() == nilTime {
        return []byte("null"), nil
    }
    return []byte(fmt.Sprintf("\"%s\"", ct.Time.Format(ctLayout))), nil
}

var nilTime = (time.Time{}).UnixNano()

func (ct *CustomTime) IsSet() bool {
    return ct.UnixNano() != nilTime
}

func (c CustomTime) Value() (driver.Value, error) {
    return driver.Value(c.Time), nil
}

func (c *CustomTime) Scan(src interface{}) error {
    switch t := src.(type) {
    case time.Time:
        c.Time = t
        return nil
    default:
        return fmt.Errorf("column type not supported")
    }
}

我的问题是,我现在需要使用恰好 3ms 的字段来格式化其他字段之一,例如 ctLayout = "2006-01-02 15:04:05.000"。

我的问题是,如何设置它,这样我就不需要复制整个结构,有没有办法可以在 Entry 结构中传递 ctLayout 字符串并在实用程序函数中获取它。我敢肯定有,但我不能为我的生活解决如何。

如果我需要创建一个 CustomTimeMS 类,那就这样吧,但它似乎有很多重复的代码。

谢谢。

标签: gotimemarshalling

解决方案


两种方式:

将导出的字段CTLayout添加到 struct Entry

type Entry struct {
        ID                int              `json:"id"`
        AuthorisedBy      string           `json:"authorisedBy"`
        ...
        ...
        AcceptedTimestamp time.Time        `json:"acceptedTimestamp"`
        CTLayout          string           `json:"-"`
}

更新MarshalJSON函数

func (ct *CustomTime) MarshalJSON() ([]byte, error) {
    if ct.Time.UnixNano() == nilTime {
        return []byte("null"), nil
    }
    return []byte(fmt.Sprintf("\"%s\"", ct.Time.Format(ct.CTLayout))), nil
}

由于CTLayout已导出,因此可以从任何地方访问它。

在调用CustomTime 值之前使用您需要的内容更新CTLayoutjson.Marshal

=====================================

添加未导出的字段

type Entry struct {
        ID                int              `json:"id"`
        AuthorisedBy      string           `json:"authorisedBy"`
        ...
        ...
        AcceptedTimestamp time.Time        `json:"acceptedTimestamp"`
        ctLayout          string
}

更新MarshalJSON函数

func (ct *CustomTime) MarshalJSON() ([]byte, error) {
    if ct.Time.UnixNano() == nilTime {
        return []byte("null"), nil
    }
    return []byte(fmt.Sprintf("\"%s\"", ct.Time.Format(ct.ctLayout))), nil
}

创建一个导出的辅助元帅函数

func (ct *CustomTime) Marshal(ctLayout string) ([]byte, error) {
        // You can do whatever else you want here
        // we'll do the obvious
        ct.ctLayout = ctLayout
        return ct.MarshalJSON()
}

称呼ct.Marshal(your layout)

如果您有权访问 CustomTime 所在的包,请直接修改 CustomTime 实例,并根据需要使Marshal未导出。


推荐阅读