poco
poco

Reputation: 3005

How to convert 8 bytes hex to DateTime

I'm attempting to parse a file that has a time stamp that i believe is 8 bytes long and looks like so in hex

00 00 00 00 DE A4 4F 4F

I do not receive the correct date/time when i parse this as an Int64. However if i skip the first 4 bytes and do something like so i get the correct datetime.

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

However I'm not certain the next files i get to parse are going to have leading 00's for the first 4 bytes. If i parse this as a ToInt64 i throw an outOfRange exception. What is the proper way to parse this?

Upvotes: 0

Views: 10557

Answers (3)

Jon Skeet
Jon Skeet

Reputation: 1502106

Are you sure the values aren't actually

DE A4 4F 4F 00 00 00 00

... for example, due to you miscounting the position in the file?

That would make more sense, and represent a little-endian 64-bit integer, which you'd convert like so:

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

(Note how much simpler this conversion code is, by the way - no messing around with LINQ, and no mulitplying the value by TicksPerSecond.)

EDIT: If it's really two little-endian 32-bit integers, arranged in big-endian order to create a 64-bit integer, then you could use:

ulong x = BitConverter.ToUInt32(data, index);
ulong y = BitConverter.ToUInt32(data, index + 4);
ulong combined = (x << 32) | y;
long seconds = unchecked ((long) combined);

Upvotes: 6

Michael Edenfield
Michael Edenfield

Reputation: 28338

Based on how you are getting a valid DateTime out of the data, it looks very much like a POSIX time_t format: number of seconds since 1/1/1970, stored as a 64-bit integer value. There are several related questions on how to convert once of these to a DateTime. See if this helps you:

How to convert a Unix timestamp to DateTime and vice versa?

Upvotes: 1

Reed Copsey
Reed Copsey

Reputation: 564641

What is the proper way to parse this?

Parsing this "properly" requires knowledge of how the binary data is stored, and what it represents exactly.

In your case, it sounds like it must be parsed as an Int32. You will need to determine the proper padding in all cases. There is no way to "know" how to "properly" parse a binary stream without knowing, in advance, the structure of the data in the stream.

As a separate issue, this statement:

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

Could be written more efficiently as:

BitConverter.ToInt32(bytes, index + 4)

Using LINQ in this case, just makes the operation very inefficient, since ToInt32 already provides an offset.

Upvotes: -1

Related Questions