Go的time.Time时间戳转换-62135596800问题分析

背景

在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的秒级时间戳

  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值