如何实现Go的time.Time与Protobuf datetime.DateTime的双向类型转换?
如何实现Go的time.Time与Protobuf datetime.DateTime的双向类型转换?
嘿,我刚好碰到过类似的场景——我们项目里部分Protobuf DTO用datetime.DateTime来表示带时区的日期时间,但内部业务逻辑全靠Go原生的time.Time来处理,毕竟它自带一堆标准工具函数,还能完美兼容各种SQL驱动。下面就聊聊怎么在这俩类型之间双向转换:
从datetime.DateTime转time.Time(相对简单)
这个方向的转换逻辑很直接,借助Protobuf提供的工具方法就能搞定,完整的实现代码如下:
import ( "errors" "time" "google.golang.org/protobuf/types/known/datetimepb" ) // DateTimeToTime converts a DateTime to a time.Time func DateTimeToTime(dt *datetimepb.DateTime) (time.Time, error) { if dt == nil { return time.Time{}, errors.New("input datetime.DateTime is nil") } t, err := dt.AsTime() if err != nil { return time.Time{}, err } return t, nil }
这里要注意对nil的datetime.DateTime做判断,避免后续转换时出现panic,同时捕获转换过程中可能出现的错误。
从time.Time转datetime.DateTime
反过来的转换同样简单,利用datetimepb.New方法就能快速生成对应的datetime.DateTime对象:
// TimeToDateTime converts a time.Time to datetime.DateTime func TimeToDateTime(t time.Time) *datetimepb.DateTime { return datetimepb.New(t) } // 如果需要处理转换错误,可以用这个版本 func TimeToDateTimeWithErr(t time.Time) (*datetimepb.DateTime, error) { dt, err := datetimepb.New(t) if err != nil { return nil, err } return dt, nil }
几个需要注意的点
- 时区保留:
time.Time和datetime.DateTime都支持时区信息,转换过程中会自动保留时区,不需要额外处理 - 包版本兼容:如果你用的是旧版Protobuf(
github.com/golang/protobuf/ptypes/datetime),转换方法会略有不同,比如旧版用ptypes.Timestamp或者ptypes.DateTime相关方法,需要对应调整 - 空值处理:当转换
time.Time时,如果传入的是零值时间,datetimepb.New会生成对应的零值DateTime对象,业务侧可以根据需求判断是否需要特殊处理
备注:内容来源于stack exchange,提问作者Woody1193
相关产品推荐
相关产品推荐

