解码时间戳与原始 DateTime 值的日期不同

Decoded Timestamp is not the same date as original DateTime value

我们有一个 .NET 应用程序,它在架构中定义了一个 DateTime,如下所示:

[ProtoMember(20)]public DateTime? Birthdate;

应用程序能够使用 protobuf-net 序列化数据,稍后在反序列化后,日期会按预期准确检索。

我现在正尝试使用 protobuf.js 在我们的 node.js 应用程序中反序列化相同的缓冲区。我在 .proto 文件中定义了该数据点,如下所示:

google.protobuf.Timestamp Birthdate = 20;

解码后得到的生日与原始数据不同。比如当日期原本是10/10/1976时,反序列化后的日期是:

"Birthdate": {
    "seconds": "4948"
}

从那个 (new Date(4948 * 1000)) 创建 JavaScript Date 时,结果是 1/1/1970。这里出了什么问题?

这归结为历史。在共享库中定义明确的 Timestamp 之前,protobuf-net 支持 DateTime 很长时间 。所以:它发明了一些允许 protobuf-net 和它自己之间往返的东西。许多年后,出现了 Timestamp,并且...简单地说,它使用了不同的存储布局。好消息是:protobuf-net 可以说那种方言,但是 因为我们无法破解现有代码,它是 "opt in".

如果你 use a Timestamp in a .proto,你可以看到 protobuf-net 生成,对于那个 .proto:

[global::ProtoBuf.ProtoMember(20, DataFormat = global::ProtoBuf.DataFormat.WellKnown)]
public global::System.DateTime? Birthdate { get; set; }

或更简单地说,匹配您现有的代码:

[ProtoMember(20,DataFormat=DataFormat.WellKnown)]public DateTime? Birthdate;

有了它 - 它应该使用相同的数据布局,你应该得到相同的值。如果您需要在平台之间交换数据,这是推荐的选项。但是,请注意,这是对现有布局的更改。如果您需要有关在不破坏现有用法的情况下进行迁移的提示,请告诉我 - 这是可能的(简短版本为 "leave field 20 as the old style; add a new property that acts similarly and uses the new format - only serialize the new one, but allow the old one to deserialize")。