1
votes

I'm trying to decode binary data that contains UNIX date stamps (time in milliseconds from 00:00:00 UTC on January 1, 1970) and can't understand why I'm unable to accurately convert an Array{UInt8,1} of 8 bytes to (ultimately) a Float64 suitable for converting to a DateTime object. My input sample is the following array from a variable named arr:

8-element Array{UInt8,1}:
0x00
0x00
0x01
0x16
0x6a
0xe0
0x68
0x80

which represents the datetime value of 2007-11-23T00:00:00

Then I try to use bit shifting to convert with the following:

Float64((Int64(arr[1]) << 56) | (Int64(arr[2]) << 48) | (Int64(arr[3]) << 40) | (Int64(arr[4]) << 32) | (Int64(arr[5]) << 24) | (Int64(arr[6]) << 16) | (Int64(arr[7]) << 8) | Int64(arr[8]))

Which gives me 1.195794e12

dividing by 1000 to get 1.195794e9 which gives me the right size for input to the function Dates.unix2datetime() which gives:

julia> Dates.unix2datetime(1.195794e9)
2007-11-23T05:00:00

which is close but not exactly what I started with of 2007-11-23T00:00:00 (I'm 5 hours off).

Can anyone shed light on where I have gone astray? Anyone offer a shorter, simpler way of doing this? In C one could use a Union to easily convert between an array representation and the target type, but unions in Julia are quite different from C. (and why do I need to divide by 1000, I would think I could get to the e9 representation directly)

1

1 Answers

2
votes

TL;DR I think your original unix timestamp was representing the date you found!

Where did you get the arr input array from?

The arr you started with does represent 1.195794e12 as can be shown with the slightly more terse:

parse(Int64,join(bits.(arr)),2) -> 1.195794e12

And you do need to divide by 1000 to go from milliseconds to seconds.

unix2datetime(x) -> DateTime
Takes the number of seconds since unix epoch 1970-01-01T00:00:00 and converts to the corresponding DateTime.

But it seems your arr represents as

Int64(Dates.datetime2unix(DateTime(2007, 11, 23, 0, 0, 0))*1000) --> 1195776000000

while Int64(Dates.datetime2unix(DateTime(2007, 11, 23, 5, 0, 0))*1000) --> 1195794000000