将c#DateTime.Now转换为二进制

将c#DateTime.Now转换为二进制,c#,datetime,binary,utc,ntp,C#,Datetime,Binary,Utc,Ntp,我问这个问题是为了学习 看看我刚刚在wireshark上捕获的udp数据包: (这是time.windows.com为了给我的电脑留出时间而回复的内容) 无论如何,我的问题是关于突出显示的最后8个字节。请注意Wireshark如何正确解析日期time.windows.com是如何生成这8个字节的?如何从DateTime.NowUtc转换到wireshark将解析为正确日期的内容? 我试过: long dateTime = DateTime.Now.ToFileTimeUtc(); var by

我问这个问题是为了学习

看看我刚刚在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年以来,我也尝试添加毫秒,但仍然显示错误的日期

编辑 下面是有关如何解析响应的示例:

但是我在哪里可以找到一个关于如何创建它的示例呢

解决方案 多亏了@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;
    }

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

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

但我们不是在看一个窗口时间。我们正在看NTP时间。在搜索“NTP消息格式”时,我找到了RFC958,其中指出“NTP时间戳表示为64位定点数字,相对于1900年1月1日的0000 UT,以秒为单位。整数部分位于前32位,小数部分位于后32位”

你如何转换?数学。或者查看此处并进行必要的调整:

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

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

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

请参阅

上的MSDN文档,谢谢您的帮助!多亏了你的回答,我现在知道如何转换NTP时间了。现在我如何创建它?我想我得往回走不?是的,这是双向的。您可以使用DateTime.Ticks获取Windows值,然后将其转换为NTP时间这也会给出错误的日期:/。也许是Endianness的原因?谢谢你的帮助!