背景
在Go的日常开发中,pb中一般都是用google的google.protobuf.Timestamp库来表示时间类型,但是在我们的程序中一般都是使用time.Time类型来表示时间,因此在给前端返回数据时,需要做一次转换,这时就会遇到-62135596800的问题。
time.Time类型转换google的Timestamp类型
now := time.Now()
t := timestamppb.New(now)
点进去看timestamppb.New的函数实现如下:
// 调用time.Unix()和time.Nanosecond()函数给Timestamp结构体赋值
func New(t time.Time) *Timestamp {
return &Timestamp{Seconds: int64(t.Unix()), Nanos: int32(t.Nanosecond())}
}
// 返回当前时间的时间戳,精度为秒
func (t Time) Unix() int64 {
return t.unixSec()
}
// 关键在这里,internalToUnix的值是-62135596800,而t.sec()返回0,所以最终Timestamp.Seconds的值为-62135596800
func (t *Time) unixSec() int64 { return t.sec() + internalToUnix }
// 返回从0001-01-01 00:00:00到当前时间的时间戳,精度为秒级
// 如果当前时间为零值(0001-01-01 00:00:00)则返回0
func (t *Time) sec() int64 {
if t.wall&hasMonotonic != 0 {
return wallToInternal + int64(t.wall<<1>>(nsecShift+1))
}
return t.ext
}
从以上源码实现我们可以得到如下结论:
1.time.Time类型的零值是0001-01-01 00:00:00 +0000 UTC
2.time.Unix()函数返回的是1970-01-01 00:00:00 +0000 UTC到当前时间的秒级时间戳
3.time.Time类型转换为Timestamp类型时,如果time.Time为零值就会出现秒级时间戳为-62135596800的问题
4.62135596800是从0000-00-00 00:00:00到1970-01-01 00:00:00的秒级时间戳