Protocol buffer时间处理(golang)

Protocol buffer

protocol buffer 是一种数据传输协议,比 Json、xml 等效率更高。

准确的说 pb 是传输协议,而后两者是序列化协议。

序列化协议有两个属性:

  • 结构化程度(人类可读性)
  • 压缩程度(序列化后的数据大小)

同一个对象序列化后,以上两个属性基本上是此消彼长、不可兼得的。因为要想人类可读就必须是字符串,且需要加入如{}[],以及换行符等符号做辅助,必然数据不能很好地压缩。

因此,pb 相对于 Json、XML 结构化很差,但是压缩程度很高,所以传输效率高。只不过人类程序员不需要去阅读序列化后的数据文本,其定义了.proto文件后直接生成客户端、服务端代码,程序员在两端都只需要关心程序中的对象(序列化前的对象和已反序列化后的对象)。

关于变量的处理

protocol buffer 本身是有时间戳的支持的,与 golang 可以融洽地结合。

实际大部分编程对时间的处理只需要精确到秒,也可以简略一点,直接使用 int32 或 int64 传输时间戳。

Timestamp

.proto文件中使用google.protobuf.Timestamp类型定义时间:

syntax = "proto3";

package pb;

import public "google/protobuf/timestamp.proto";

message person{
  google.protobuf.Timestamp birthday = 1;
}

对应生成的 .pb.go 文件中类型为*timestamp.Timestamp

type Person struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Birthday *timestamp.Timestamp `protobuf:"bytes,1,opt,name=birthday,proto3" json:"birthday,omitempty"`
}

其中,timestamp.Timestamp的 message 类型定义如下

message Timestamp {
  // Represents seconds of UTC time since Unix epoch
  // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
  // 9999-12-31T23:59:59Z inclusive.
  int64 seconds = 1;

  // Non-negative fractions of a second at nanosecond resolution. Negative
  // second values with fractions must still have non-negative nanos values
  // that count forward in time. Must be from 0 to 999,999,999
  // inclusive.
  int32 nanos = 2;
}

go 语言 time.Time 类型与 timestamp.Timestamp互相转换使用github.com/golang/protobuf/ptypes包下方法:

package pb

import (
	"fmt"
	"github.com/golang/protobuf/ptypes"
	"time"
)

func TimeStampFeature() {
	//Timestamp 转 Time
	//获取的是系统时区的时间戳
	pbTimestamp := ptypes.TimestampNow()
	//此方法默认 UTC 时区
	goTime, _ := ptypes.Timestamp(pbTimestamp)
	//设定为系统时区
	fmt.Println(goTime.Local())

	//Time 转 Timestamp
	goTime2 := time.Now()
	pbTimestamp2, _ := ptypes.TimestampProto(goTime2)
	fmt.Println(pbTimestamp2)
}

输出为:

=== RUN   TestTimeStampFeature
2020-10-26 14:10:48.69129 +0800 CST
seconds:1603692648  nanos:691445000
--- PASS: TestTimeStampFeature (0.00s)
PASS

秒级时间戳

若只时间处理只精确到秒,则不必使用 time.Timetimestamp.Timestamp来处理和传输时间戳,直接使用 int32int64来表示秒级时间戳,免去类型互相转换。

posted @ 2020-10-26 14:26  wangbs95  阅读(4744)  评论(0编辑  收藏  举报