使用 ptypes.Timestamp 与 timestamppb.Timestamp.AsTime 进行时间转换

问题描述 投票:0回答:1

自从开始在

go
中使用协议缓冲区以来,我考虑了通过
timestamppb.Timestamp
time.Time
 结构转换为 
ptypes.Timestamp
结构的惯用方法,例如:

t, err := ptypes.Timestamp(pbTimestamp)
if err != nil {
    // some error handling
}

但是,正如我刚刚发现的,

timestamppb.Timestamp
还有成员函数
AsTime
,它可以促进相同的转换,但只返回
time.Time
值,而不返回
error

由于

ptypes.Timestamp
确实在
time.Time
之上返回错误,这表明存在失败的可能性,我想知道
AsTime
的使用是否可以被认为是安全的。从 godocs 来看,似乎没有什么需要考虑的,但是没有返回转换错误似乎有点奇怪。有没有人对此有任何解释?

go time protocol-buffers
1个回答
0
投票

tl;dr 你不能跳过验证检查。


这里的问题是由零值的语义差异引起的。

[...] 是 1 年 1 月 1 日 00:00:00.000000000 UTC。由于这个时间在实践中不太可能出现,IsZero 方法提供了一种简单的方法来检测尚未显式初始化的时间。

  • timestamppb.Timestamp
    是零纪元,即 UTC 时间 1970 年 1 月 1 日午夜。

这意味着零

timestamppb.Timestamp
映射到有效的非零
time.Time
。事实上:

(*timestamppb.Timestamp)(nil).AsTime().IsZero() // FALSE!

而:

timestamppb.New(time.Time{}).AsTime().IsZero() // true

这就是旧的

ptypes.Timestamp
函数可能返回错误的原因。它内置了一个验证步骤,以考虑原始时间戳无效的情况——例如如果是
nil
。因此,请勿使用
AsTime
直接替代
ptypes.Timestamp

使用

IsValid
CheckValid
代替,然后
AsTime
:


if myProtoTs.IsValid() {
    t := myProtoTs.AsTime()
    // do something with t
}

进一步阅读,以及原型维护者的评论:https://github.com/golang/protobuf/issues/1457

© www.soinside.com 2019 - 2024. All rights reserved.