Node.js 解码的时间戳与原始日期时间值的日期不同

Node.js 解码的时间戳与原始日期时间值的日期不同,node.js,protocol-buffers,protobuf-net,protobuf.js,Node.js,Protocol Buffers,Protobuf Net,Protobuf.js,我们有一个.NET应用程序,它在模式中定义了DateTime,如下所示: [ProtoMember(20)]public DateTime? Birthdate; 应用程序能够使用protobuf-net对数据进行序列化,然后在反序列化后,按照预期准确检索日期 我现在正尝试使用protobuf.js反序列化node.js应用程序中的相同缓冲区。我在.proto文件中定义了该数据点,如下所示: google.protobuf.Timestamp Birthdate = 20; 解码后,生成的出

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

[ProtoMember(20)]public DateTime? Birthdate;
应用程序能够使用
protobuf-net
对数据进行序列化,然后在反序列化后,按照预期准确检索日期

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

google.protobuf.Timestamp Birthdate = 20;
解码后,生成的出生日期与原始数据不同。例如,当日期最初为1976年10月10日时,反序列化日期为:

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

从该日期(
新日期(4948*1000)
)创建JavaScript
日期时,结果为1/1/1970。这里出了什么问题?

这可以归结为历史。protobuf net支持
DateTime
很长一段时间后,共享库中才出现定义良好的
时间戳。所以:它发明了一种允许protobuf网络和自身之间往返的东西。许多年后,出现了
时间戳
,并且。。。简单地说,它使用不同的存储布局。好消息是:protobuf-net可以讲这种方言,但因为我们不能破坏现有的代码,所以它是“选择加入”

如果您这样做,您可以看到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保留为旧样式;添加一个行为类似并使用新格式的新属性-仅序列化新属性,但允许旧属性反序列化”).

4948秒距离纪元只有~1:22:28,所以日期应该是1970年1月1日。也许你忘了包括天、月和年?是的,似乎有些东西遗漏了,但没有什么可以遗漏的,因为协议缓冲区中的数据是正确的,它在C#应用程序中被正确反序列化,而不是在JS应用程序中。谢谢你提供的信息!我会让你知道我们是否可以使用更多关于迁移策略的信息。似乎我们可以研究当前反序列化的模式,以避免迁移。你能看到它在转换这些日期时做了什么吗?我们注意到,如果你用
,除以2,加上从历元算起的天数,我们就得到了正确的日期。但是这只在没有提供NANO的情况下有效(时间是00:00)。哦,我可以确切地告诉你protobuf net默认使用的格式。我也可以说我很后悔——当时这似乎是个好主意,但是。。。给你:(寻找DateTime)。如果你能换成“知名”类型,那将是我的建议。