首页 > 解决方案 > 解码时间戳与原始 DateTime 值不同的日期

问题描述

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

[ProtoMember(20)]public DateTime? Birthdate;

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

我现在正在尝试使用protobuf.js. 我在.proto文件中定义了该数据点,如下所示:

google.protobuf.Timestamp Birthdate = 20;

解码后,生成的出生日期与原始数据不同。例如,当日期最初是 1976 年 10 月 10 日时,反序列化的日期为:

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

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

标签: node.jsprotocol-buffersprotobuf-netprotobuf.js

解决方案


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

如果您在 .proto 中使用 aTimestamp,您可以看到 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;

有了它 - 它应该使用相同的数据布局,并且您应该获得相同的值。如果您需要在平台之间交换数据,这是推荐的选项。但是,请注意,这是对现有布局的更改。如果您需要在不破坏现有用法的情况下进行迁移的提示,请告诉我 - 这是可能的(简短版本是“将字段 20 保留为旧样式;添加一个行为类似并使用新格式的新属性 - 仅序列化新的一,但允许旧的反序列化“)。


推荐阅读