与Protobuf一起使用的日期和时间类型

asg*_*aut 48 protocol-buffers

我正在考虑使用Protocol Buffers在Linux和基于Windows的系统之间进行数据交换.

什么是推荐的发送日期/时间(时间戳)值的格式?序列化时该字段应该很小.

Evg*_*kov 84

Timestamp自protobuf 3.0以来就有消息类型,这就是如何在模型中创建它:

syntax = "proto3";

import "google/protobuf/timestamp.proto";

message MyMessage {
    google.protobuf.Timestamp my_field = 1;
}
Run Code Online (Sandbox Code Playgroud)

timestamp.proto file包含使用Timestamp的示例,包括与Linux和Windows程序相关的示例.

示例1:计算POSIX的时间戳time().

Timestamp timestamp;
timestamp.set_seconds(time(NULL));
timestamp.set_nanos(0);
Run Code Online (Sandbox Code Playgroud)

示例2:从POSIX计算时间戳gettimeofday().

struct timeval tv;
gettimeofday(&tv, NULL);

Timestamp timestamp;
timestamp.set_seconds(tv.tv_sec);
timestamp.set_nanos(tv.tv_usec * 1000);
Run Code Online (Sandbox Code Playgroud)

示例3:从Win32计算时间戳GetSystemTimeAsFileTime().

FILETIME ft;
GetSystemTimeAsFileTime(&ft);
UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;

// A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
// is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
Timestamp timestamp;
timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
Run Code Online (Sandbox Code Playgroud)

  • 不确定这是否值得一个完整的答案,但问题询问了时间戳和日期,因此当您不需要更高的精度时请考虑 google.type.Date 。 (4认同)
  • @micseydel:OP 要求使用“小”数据类型。google.type.Date 是 3 个整数,其精度比简单地发送带有 Unix 时间戳的 int64 低。除了易于人类阅读之外,很少有情况需要 google.type.Date 。当然,Protobuf 的二进制格式会尽可能地组合 3 个整数,但一般来说,如果大小很重要,它似乎并不理想。 (3认同)

Jes*_*erE 38

虽然你没有说你正在使用哪种语言或者你需要什么样的精度,但我建议使用Unix时间编码成a int64.它在大多数语言和平台上都很容易处理(请参阅此处的Windows示例),Protobufs将使用varint-encoding来保持较小的大小而不会过多地限制可表示的范围.

  • 直到2038年才使用4个字节...无法击败它 (11认同)
  • 我的观点是:如果你在protobuf中使用Unix Time,你将只使用4个字节......这意味着Unix时间很好....这就是我所说的!顺便说一下,我在2038年之后添加了一个警告,即4个字节将不再足够 (10认同)
  • Unix时间仅消耗4个字节,这是一种非常有效的编码.但是对于2038年之后的日期,它需要超过4个字节 (4认同)
  • 不是5吗?Varint编码. (4认同)
  • Unix时间没有根据占用的字节数来指定,它被定义为自纪元以来的秒数.传统上它已被表示为32位整数,但大多数操作系统目前使用64位整数. (2认同)
  • 不。您通常不需要存储时区。您的显示功能可以采用当前时区并进行转换。 (2认同)

Har*_*dan 7

在最新的protobuf版本(3.0)中-对于C#,Timestamp提供了WellKnownType。检查一下