C# 如何将8字节十六进制转换为DateTime

C# 如何将8字节十六进制转换为DateTime,c#,datetime,C#,Datetime,我正在尝试解析一个文件,它有一个时间戳,我相信它有8个字节长,在十六进制中看起来也是这样 00德A4 4F 4F 当我将其解析为Int64时,我没有收到正确的日期/时间。但是,如果我跳过前4个字节并执行类似操作,那么我将获得正确的日期时间 TimeSpan span = TimeSpan.FromTicks(BitConverter.ToInt32(bytes.Skip(index).Take(8).ToArray(),4) * TimeSpan.TicksPerSecond); DateTim

我正在尝试解析一个文件,它有一个时间戳,我相信它有8个字节长,在十六进制中看起来也是这样

00德A4 4F 4F

当我将其解析为Int64时,我没有收到正确的日期/时间。但是,如果我跳过前4个字节并执行类似操作,那么我将获得正确的日期时间

TimeSpan span = TimeSpan.FromTicks(BitConverter.ToInt32(bytes.Skip(index).Take(8).ToArray(),4) * TimeSpan.TicksPerSecond);
DateTime t = new DateTime(1970, 1, 1).Add(span);
StartTime = TimeZone.CurrentTimeZone.ToLocalTime(t);
但是,我不确定我要解析的下一个文件的前4个字节是否有前导00。如果我将其解析为ToInt64,则抛出outOfRange异常。正确的解析方法是什么

正确的解析方法是什么

“正确”地解析这个过程需要了解二进制数据是如何存储的,以及它确切地表示了什么

在您的情况下,听起来它必须被解析为
Int32
。您需要在所有情况下确定适当的填充。如果事先不知道流中数据的结构,就无法“知道”如何“正确”解析二进制流

作为一个单独的问题,本声明:

BitConverter.ToInt32(bytes.Skip(index).Take(8).ToArray(),4)
可以更有效地编写为:

BitConverter.ToInt32(bytes, index + 4)
在这种情况下使用LINQ只会使操作非常低效,因为它已经提供了一个偏移量

正确的解析方法是什么

“正确”地解析这个过程需要了解二进制数据是如何存储的,以及它确切地表示了什么

在您的情况下,听起来它必须被解析为
Int32
。您需要在所有情况下确定适当的填充。如果事先不知道流中数据的结构,就无法“知道”如何“正确”解析二进制流

作为一个单独的问题,本声明:

BitConverter.ToInt32(bytes.Skip(index).Take(8).ToArray(),4)
可以更有效地编写为:

BitConverter.ToInt32(bytes, index + 4)

在这种情况下,使用LINQ只会使操作非常低效,因为已经提供了偏移量。

根据从数据中获取有效日期时间的方式,它看起来非常像POSIX time格式:自1970年1月1日起的秒数,存储为64位整数值。关于如何将其中一个转换为DateTime,有几个相关的问题。看看这是否有助于您:


根据从数据中获取有效日期时间的方式,它看起来非常像POSIX time格式:自1970年1月1日以来的秒数,存储为64位整数值。关于如何将其中一个转换为DateTime,有几个相关的问题。看看这是否有助于您:


您确定这些值实际上不正确吗

。。。例如,由于您错误计算了文件中的位置

这将更有意义,并表示一个小的endian 64位整数,您可以这样转换:

static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0,
                                              DateTimeKind.Utc);

...

long seconds = BitConverter.ToInt64(data, index);
DateTime date = Epoch + TimeSpan.FromSeconds(seconds);
(顺便说一句,请注意此转换代码要简单得多-没有弄乱LINQ,也没有通过
TicksPerSecond
复制值)

编辑:如果它真的是两个小尾数32位整数,按大尾数顺序排列以创建一个64位整数,那么您可以使用:

ulong x = BitConverter.ToUInt32(data, index);
ulong y = BitConverter.ToUInt32(data, index + 4);
ulong combined = (x << 32) | y;
long seconds = unchecked ((long) combined);
ulong x=BitConverter.ToUInt32(数据、索引);
ulong y=位转换器.ToUInt32(数据,索引+4);

ulong combined=(x您确定这些值实际上不正确吗

…例如,由于您错误计算了文件中的位置

这将更有意义,并表示一个小的endian 64位整数,您可以这样转换:

static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0,
                                              DateTimeKind.Utc);

...

long seconds = BitConverter.ToInt64(data, index);
DateTime date = Epoch + TimeSpan.FromSeconds(seconds);
(顺便说一句,请注意此转换代码要简单得多-没有弄乱LINQ,也没有通过
TicksPerSecond
复制值)

编辑:如果它真的是两个小尾数32位整数,按大尾数顺序排列以创建一个64位整数,那么您可以使用:

ulong x = BitConverter.ToUInt32(data, index);
ulong y = BitConverter.ToUInt32(data, index + 4);
ulong combined = (x << 32) | y;
long seconds = unchecked ((long) combined);
ulong x=BitConverter.ToUInt32(数据、索引);
ulong y=位转换器.ToUInt32(数据,索引+4);

ulong combined=(x请不要在标题前加上“C#”之类的前缀。这就是标签的作用。请不要在标题前加上“C#”诸如此类。这就是标签的作用。在十六进制编辑器中查看文件,它的读数为00 DE A4 4F 4F。我最初尝试了与上面类似的东西,但我得到了一个参数超出范围的异常。@poco:文件真的只有8个字节吗?看起来很奇怪。是什么创建了该文件?该文件实际上相当复杂翁先生,但是我知道这8个字节前后对应的字节是什么。前4个字节可能只是填充,但是我很有信心这8个字节就是日期时间。你编辑的结果是总的,我现在踢自己,因为我应该在几个小时前提出来。非常感谢你的帮助p先生。在十六进制编辑器中查看文件,它的读数为00 DE A4 4F 4F。我最初尝试了与您上面的类似的东西,但是我得到了一个参数超出范围的异常。@poco:文件真的只有8字节吗?看起来很奇怪。是什么创建了文件?文件实际上相当长,先生,但是我知道b是什么字节对应于这8个字节之前和之后。前4个字节可能只是填充,但我很有信心这8个字节就是日期时间。从那时起,你的编辑使总数增加,我现在踢自己,因为我应该在几个小时前就想到了。非常感谢你的帮助,先生。