编组结构时间的通用方法.使用自定义格式将时间字段转换为JSON [英] Generic approach for marshalling a struct's time.Time fields to JSON with custom formatting
问题描述
我的数据模型定义了多个结构,它们都具有两个共同的字段:StartDate
和EndDate
.我需要将这两个字段在经过编组的JSON中格式化为2018-09-21
,因此结构实现了Marshaller
接口:
My data model defines multiple structs that all have two fields in common: a StartDate
and an EndDate
. I need those two fields to be formatted as 2018-09-21
in the marshalled JSON, therefore the structs implement the Marshaller
interface:
type Results struct {
Source string `json:"source"`
StartDate time.Time
EndDate time.Time
}
type WeightedResults struct {
Source string `json:"source"`
StartDate time.Time
EndDate time.Time
}
func (r Results) MarshalJSON() ([]byte, error) {
type Alias Results
if equalDate(r.StartDate, r.EndDate) {
return json.Marshal(&struct {
Date string `json:"date"`
Alias
}{
Date: r.StartDate.Format(dateFormat),
Alias: (Alias)(r),
})
}
return json.Marshal(&struct {
StartDate string `json:"start_date"`
EndDate string `json:"end_date"`
Alias
}{
StartDate: r.StartDate.Format("2006-01-02"),
EndDate: r.EndDate.Format("2006-01-02"),
Alias: (Alias)(r),
})
}
func (r WeightedResults) MarshalJSON() ([]byte, error) {
type Alias WeightedResults
if equalDate(r.StartDate, r.EndDate) {
return json.Marshal(&struct {
Date string `json:"date"`
Alias
}{
Date: r.StartDate.Format(dateFormat),
Alias: (Alias)(r),
})
}
return json.Marshal(&struct {
StartDate string `json:"start_date"`
EndDate string `json:"end_date"`
Alias
}{
StartDate: r.StartDate.Format("2006-01-02"),
EndDate: r.EndDate.Format("2006-01-02"),
Alias: (Alias)(r),
})
}
上面的解决方案可以正常工作,但是会产生大量的代码重复.有什么方法可以重构MarshalJSON
的两个实现以使用相同的逻辑/代码?我很清楚Go还没有提供泛型,但是必须解决这个问题,对吗?
The solution above works fine but yields lots of code duplication. Is there any way to refactor both implementations of MarshalJSON
to use the same logic/code? I am well aware that Go does not offer Generics (yet), but there has to be another way around this issue, right?
推荐答案
您的自定义封送拆封器不应位于结构上,而应位于嵌入time.Time
的自定义类型上:
Your custom marshaler should not be on the structs, but on a custom type that embeds time.Time
:
type MyTime struct {
time.Time
}
func (t MyTime) MarshalJSON() ([]byte, error) {
return json.Marshal(t.Format("2006-01-02"))
}
然后在您想要的任何地方使用此类型.
Then use this type everywhere you want.
type Results struct {
Source string `json:"source"`
StartDate MyTime
EndDate MyTime
}
这篇关于编组结构时间的通用方法.使用自定义格式将时间字段转换为JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!