Go Gin框架下如何自动解析请求体中的时间戳为time.Time?
解决方案:在Gin中自动将时间戳解析为time.Time
嘿,这个需求我刚好处理过!直接给你结论:有简洁的实现方式,而且自行编写转换逻辑不算重复造轮子——因为标准库的time.Time默认不支持从整数时间戳反序列化,我们只是在适配业务常用的时间格式而已。
核心思路:自定义类型扩展JSON序列化能力
Gin的BindJSON依赖Go标准库的encoding/json,而原生time.Time只认RFC3339格式的字符串(比如"2006-01-02T15:04:05Z07:00")。要让它支持整数时间戳,我们只需要给time.Time套一层自定义类型,实现json.Unmarshaler接口,就能让Gin自动完成解析。
具体代码实现
import ( "encoding/json" "net/http" "time" "github.com/gin-gonic/gin" ) // 自定义时间类型,包装原生time.Time type TimestampTime time.Time // 实现json.Unmarshaler接口,处理毫秒级时间戳(匹配你给出的1589887669644) func (t *TimestampTime) UnmarshalJSON(data []byte) error { // 先把JSON字节解析成整数 var timestamp int64 if err := json.Unmarshal(data, ×tamp); err != nil { return err } // 毫秒转时间对象,赋值给自定义类型 *t = TimestampTime(time.UnixMilli(timestamp)) return nil } // 可选:如果需要返回时也输出时间戳,实现MarshalJSON接口 func (t TimestampTime) MarshalJSON() ([]byte, error) { // 把时间转成毫秒级时间戳 timestamp := time.Time(t).UnixMilli() return json.Marshal(timestamp) } // 修改结构体,使用自定义时间类型 type BodyType struct { YourDate TimestampTime `json:"YourDate"` } func doThingWithPost(c *gin.Context) { var theBody BodyType // 绑定失败记得返回错误 if err := c.BindJSON(&theBody); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } // 随时可以转成原生time.Time使用 nativeTime := time.Time(theBody.YourDate) c.JSON(http.StatusOK, gin.H{"data": theBody.YourDate, "native_time": nativeTime}) } func main() { r := gin.Default() r.POST("/", doThingWithPost) r.Run() }
为什么不算重复造轮子?
- 标准库的
time.Time设计初衷是处理标准时间格式字符串,并没有内置对整数时间戳的支持,这属于业务场景的合理扩展。 - 我们只是对原生
time.Time做了一层包装,核心的时间转换逻辑还是用的标准库函数(time.UnixMilli),没有重复实现时间处理的核心功能,完全符合“不重复造轮子”的原则。
小补充
如果你的时间戳是秒级(比如1589887669),只需要把代码里的time.UnixMilli换成time.Unix(timestamp, 0)就可以了。
内容的提问来源于stack exchange,提问作者juan garcia
相关产品推荐
相关产品推荐

