我需要在协议缓冲区消息中序列化.NET DateTime值。
我的计划是使用DateTime.ToBinary(),然后在消息中传递64位返回值。但我不确定选择什么作为协议缓冲数据类型来表示它。
我想我应该在使用fixed64(或sfixed64)数据类型时对感到困惑。
我假设在这种情况下我会使用签名类型,因为DateTime.ToBinary()返回的值可以是负数也可以是正数。
答案 0 :(得分:9)
嗯,您肯定希望int64
或sfixed64
能够应对正在签名的值。
刚刚进行了快速测试,DateTime.Now.ToBinary()
使用int64
以10个字节进行编码,而sfixed64
将始终使用8个字节。基本上,可变长度编码对于小数字很有用,但是对于大数字而言变得比固定编码大。 (这与使用UTF-8而不是UTF-16的权衡相同 - ASCII字符可以在单个字节中以UTF-8编码,但稍后在代码点上最终编码为2然后3个字节,而UTF -16总是在BMP中使用2个字节作为字符。)
我的猜测是DateTime.ToBinary()
值可能非常大(不知道其具体内容的详细信息),因此sfixed64
更合适。
这有意义吗?
答案 1 :(得分:4)
在protobuf-net中,我使用渐变式方法(事实上,如果你只使用DateTime
,它会为你处理所有这些) - 等效的.proto是这样的:
message DateTime {
optional sint64 value = 1; // the offset (in units of the selected scale)
// from 1970/01/01
optional TimeSpanScale scale = 2 [default = DAYS]; // the scale of the
// timespan
enum TimeSpanScale {
DAYS = 0;
HOURS = 1;
MINUTES = 2;
SECONDS = 3;
MILLISECONDS = 4;
MINMAX = 15; // dubious
}
}
即。如果DateTime
可以在整天表达,我只发送自1970年以来的天数等 - 加上一个小标记到比例。这意味着可以更有效地发送日期,但对于其他比例而言,它并不会花费更多。
就个人而言,我不会使用ToBinary()
- 我会明确地使用已知时期的已知尺度的偏移(例如unix时代)。这使得它在平台之间更加便携。但是,如果您发送(例如)毫秒偏移量,则固定比例通常比变长比例更有效。是否需要签名或未签名取决于您是否需要在纪元之前的日期;-p
答案 2 :(得分:0)
您应该使用带符号的64位数字,而不是因为DateTime
可能是负数,而是因为ToBinary
方法返回Int64
,这是一个带符号的64位数字