代码之家  ›  专栏  ›  技术社区  ›  Louis Somers

这6行C中一定有bug,否则.Net DateTime类型与其他实现不一致?

  •  -1
  • Louis Somers  · 技术社区  · 5 年前

    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.
    

    我试图用以下C代码验证这一点,但得到了不同的结果:

    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")));
    

    输出为:

    时间戳64:1970-01-01 00:00:00.0000000-2514-05-30 04:39:42.9999900

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

    请注意,这还不是MsgPack实现,我首先需要在开始使用单元测试验证真正的代码之前正确地理解它。如果基础已经被打破,那么用这些移位的位在小端和大端之间进行转换只会增加更多的混乱。。。。

    1 回复  |  直到 5 年前
        1
  •  2
  •   Peter Duniho    5 年前

    TimeSpan maxNanoSecSpan = new TimeSpan(maxNanoSec * 100); .