Как преобразовать 8-байтовый гекс в DateTime - PullRequest
0 голосов
/ 07 марта 2012

Я пытаюсь проанализировать файл с меткой времени, которая, по моему мнению, имеет длину 8 байт и выглядит так в шестнадцатеричном формате

00 00 00 00 DE А4 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);

Однако я не уверен, что следующие файлы, которые я получу для анализа, будут иметь первые 00 для первых 4 байтов. Если я анализирую это как ToInt64, я выбрасываю исключение outOfRange. Как правильно разобрать это?

Ответы [ 3 ]

5 голосов
/ 07 марта 2012

Вы уверены, что значения не на самом деле

DE A4 4F 4F 00 00 00 00

... например, из-за неправильного подсчета позиции в файле?

Чтобудет иметь больше смысла, и будет представлять 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);
0 голосов
/ 07 марта 2012

Исходя из того, как вы получаете действительный DateTime из данных, он очень похож на формат POSIX time_t: количество секунд с 01.01.1970, сохраненное как 64-битное целочисленное значение. Есть несколько связанных вопросов о том, как преобразовать один из них в DateTime. Посмотрите, поможет ли это вам:

Как преобразовать метку времени Unix в DateTime и наоборот?

0 голосов
/ 07 марта 2012

Как правильно проанализировать это?

Для синтаксического анализа этого «правильно» требуется знание о том, как хранятся двоичные данные и что именно они представляют.

В вашем случае это звучит так, как будто оно должно быть проанализировано как Int32.Вам нужно будет определить правильный отступ во всех случаях.Невозможно «знать», как «правильно» анализировать двоичный поток, не зная заранее структуры данных в потоке.

В качестве отдельной проблемы этот оператор:

BitConverter.ToInt32(bytes.Skip(index).Take(8).ToArray(),4)

Можно записать более эффективно как:

BitConverter.ToInt32(bytes, index + 4)

Использование LINQ в этом случае просто делает операцию очень неэффективной, поскольку ToInt32 уже обеспечивает смещение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...