【问题标题】:Convert c# DateTime.Now to Binary将 c# DateTime.Now 转换为二进制
【发布时间】:2017-07-04 22:25:36
【问题描述】:

我问这个问题是为了学习。

看看我刚刚在wireshark上捕获的这个udp数据包:

(这是 time.windows.com 的回复,以便将时间分配给我的计算机)

无论如何,我的问题是关于突出显示的最后 8 个字节。请注意 Wireshark 如何正确解析日期。 time.windows.com 是如何生成这 8 个字节的?如何从DateTime.NowUtc 转到wireshark 将解析为正确日期的内容?

我试过了:

long dateTime = DateTime.Now.ToFileTimeUtc();
var bytes = BitConverter.GetBytes(dateTime);

但是当我发送这 8 个字节时,wireshark 将该日期解析为“4/15/1998 11:27:52 AM”,这已经很遥远了。

自 1970 年以来,我也尝试添加毫秒,但仍然显示错误的日期。

编辑

以下是有关如何解析响应的示例: http://davidnakoko.com/2013/07/c-get-network-time-from-ntp-server/

但是我在哪里可以找到有关如何创建它的示例?

解决方案

感谢@adjan 和@RayFischer 的回答,我想出了一个解决方案。这里是:

    public static byte[] ConvertToNtp(DateTime datetime)
    {
        ulong milliseconds = (ulong)((datetime - new DateTime(1900, 1, 1)).TotalMilliseconds);

        ulong intpart = 0, fractpart = 0;
        var ntpData = new byte[8];

        intpart = milliseconds / 1000;
        fractpart = ((milliseconds % 1000) * 0x100000000L) / 1000;

        //Debug.WriteLine("intpart:      " + intpart);
        //Debug.WriteLine("fractpart:    " + fractpart);
        //Debug.WriteLine("milliseconds: " + milliseconds);

        var temp = intpart;
        for (var i = 3; i >= 0; i--)
        {
            ntpData[i] = (byte)(temp % 256);
            temp = temp / 256;
        }

        temp = fractpart;
        for (var i = 7; i >= 4; i--)
        {
            ntpData[i] = (byte)(temp % 256);
            temp = temp / 256;
        }
        return ntpData;
    }

【问题讨论】:

    标签: c# datetime binary utc ntp


    【解决方案1】:

    对于所有操作系统,都有两个重要的价值: 1)“时代” 2) 区间

    epoch 描述了该值所代表的时间间隔。从 MS 帮助中引用,DateTime.Ticks “表示自 0001 年 1 月 1 日午夜 12:00:00 以来经过的 100 纳秒间隔数”。

    但我们并不是在看 Windows 时代。我们正在查看 NTP 时间。搜索“NTP 消息格式”时,我发现 RFC958 说“NTP 时间戳表示为 64 位定点数,以相对于 1900 年 1 月 1 日 0000 UT 为单位的秒数。整数部分位于前 32 位中,而最后 32 位的小数部分"

    你如何转换?数学。或查看此处并进行必要的调整: How to convert NTP time to Unix Epoch time in C language (Linux)

    【讨论】:

    • 感谢您的帮助!感谢您的回答,我现在知道如何转换 NTP 时间。现在我该如何创建它?我想我只需要倒退不?
    • 是的,它是双向的。您可以使用 DateTime.Ticks 获取 Windows 值,然后转换为 NTP 时间
    【解决方案2】:

    .Net 提供了将 DateTime 转换为 64 位二进制表示并返回 DateTime 的方法。

    DateTime localDate = new DateTime(2010, 3, 14, 2, 30, 0, DateTimeKind.Local);
    long binLocal = localDate.ToBinary();
    DateTime localDate2 = DateTime.FromBinary(binLocal);
    

    请参阅DateTime.ToBinary 上的 MSDN 文档

    【讨论】:

      【解决方案3】:

      根据您链接的代码,您有:

      UInt64 milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L);
      
      DateTime networkDateTime = (new DateTime(1900, 1, 1)).AddMilliseconds((long)milliseconds);
      

      因此,您会看到 8 个字节是自 1900 年 1 月 1 日以来的毫秒数。因此,要生成这样的时间戳,您可以这样做

      ulong milliseconds = (ulong)((DateTime.Now() - new DateTime(1900, 1, 1)).TotalMilliseconds);
      

      【讨论】:

      • 这也给出了不正确的日期:/。也许是字节序的原因?感谢您的帮助!
      猜你喜欢
      • 1970-01-01
      • 2019-03-18
      • 1970-01-01
      • 2012-12-26
      • 2014-04-21
      • 1970-01-01
      • 2016-10-02
      • 2014-03-24
      相关资源
      最近更新 更多