c# - 将 MsgPack 时间戳 64 字段转换为 DateTime 时出现错误结果

标签 c# datetime timestamp msgpack

我正在尝试实现 MsgPack TimeStamp 64 type在 C# 中。规范是这样说的:

timestamp 64 stores the number of seconds and nanoseconds that have elapsed since 1970-01-01 00:00:00 UTC
in 32-bit unsigned integers:
+--------+--------+--------+--------+--------+------|-+--------+--------+--------+--------+
|  0xd7  |   -1   | nanosec. in 30-bit unsigned int |   seconds in 34-bit unsigned int    |
+--------+--------+--------+--------+--------+------^-+--------+--------+--------+--------+

* Timestamp 64 format can represent a timestamp in [1970-01-01 00:00:00.000000000 UTC, 2514-05-30 01:53:04.000000000 UTC) range.
* In timestamp 64 and timestamp 96 formats, nanoseconds must not be larger than 999999999.

Note that the seconds field is thirty-four bits, not thirty-two. So the max value can be computed by shifting a 32-bit max value unsigned int left two bits and setting the now-cleared two least-significant bits.

I tried to verify this with the following C# code but got different results:

DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); // the zero starting point
long maxSecs = ((long)uint.MaxValue << 2) | 3; // 17179869183
long maxNanoSec = 999999999; // not uint.MaxValue
TimeSpan maxNanoSecSpan = new TimeSpan(maxNanoSec * 100); // 1 tick = 100 nanosec.
DateTime MaxFExt8 = epoch.AddSeconds(maxSecs).Add(maxNanoSecSpan); 
Console.WriteLine(string.Concat("Timestamp 64 : ", epoch.ToString("yyyy-MM-dd HH:mm:ss.fffffff"), " - ", MaxFExt8.ToString("yyyy-MM-dd HH:mm:ss.fffffff")));

输出为:

Timestamp 64 : 1970-01-01 00:00:00.0000000 - 2514-05-30 04:39:42.9999900

这太长了 2 小时 46 分 39 秒...

opening an issue之后关于差异,其他人检查后发现他们得到的结果与规范相同。一个使用 MacOS 内置的 NSDate 类型,另一个使用 ruby​​。

我认为我的6行代码一定有一个bug,但我已经盯着它看了太久了......

附注请注意,这还不是 MsgPack 实现,我首先需要正确执行此操作,然后才能开始使用单元测试验证我的真实代码。如果基础已经被破坏,那么使用这些移位位在小端和大端之间进行转换只会增加更多的困惑......

最佳答案

在应该除法的时候却乘以纳秒:Time Span max NanoSec Span = new TimeSpan(max NanoSec * 100);

关于c# - 将 MsgPack 时间戳 64 字段转换为 DateTime 时出现错误结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66808246/

相关文章:

java - ServerValue.TIMESTAMP 在 Firebase 中保存和检索时间戳

google-apps-script - 按下按钮时插入时间戳的脚本建议

c# - 调用函数时 REST Web 服务 400 错误

java - Android 中的 ISO8601 日期字符串转为 Long

javascript - AngularJS 错误的 unix 时间解析结果

python - Pandas read_csv 将字符串转换为日期时间并保存到数据库 Python

.net - JavaScriptSerializer UTC DateTime 问题

c# - 使用来自其他库的值的 Swig 枚举

c# - Winforms MessageBox 的形状

c# - 异步向主线程发送信号