Darren Beale Darren Beale - 1 month ago 10
PHP Question

Converting a 32bit number in a proprietary timestamp with PHP

I have a 32 bit number represented as a HEX string that I need to convert to a timestamp following these rules:

Timestamp specification

What I want to check is that I'm not doing something glaringly stupid? Does my conversion look sane given the timestamp specification?

I've put together the following code to do this. I know PHP isn't the best for this sort of work but it's part of a larger legacy application all written in PHP.

$t
is taken from an XML file of readings, one every 5 mins.

// convert the hex string to binary
// sprintf pads leading zeros
$binStr = sprintf('%032s', base_convert($t, 16, 2));

//get a decimal representation so we can use the bitwise operator on it
// I know I could have converted straight to decimal, but I'm debugging
$decimal = bindec($binStr);

// get the first 6 bits
$min = $decimal & bindec('111111');

// drop the first 8 bits then apply a mask to the next 5
$hour = ($decimal >> 8) & bindec('11111');

// drop the first 15 bits then apply a mask to the next 1
$daylightSaving = ($decimal >> 15) & 1;

// etc
$day = ($decimal >> 16) & bindec('11111');
$yearLsb = ($decimal >> 21) & bindec('111');
$month = ($decimal >> 24) & bindec('1111');
$yearMsb = ($decimal >> 28) & bindec('1111');

Logger::debug(
$t . " Incoming timestamp converted to \n" .
$binStr . " then converted to \n" .
" Day: " . $day . "\n" .
" Month: " . $month . "\n" .
" Year: " . $yearMsb . $yearLsb . "\n" .
" Hour: " . $hour . "\n" .
" Min: " . $min . "\n" .
" Daylight saving: ". $daylightSaving
);


The output for the last entry in the file is:

2DAC1B0A Incoming timestamp converted to
00101101101011000001101100001010 then converted to
Day: 12
Month: 13
Year: 25
Hour: 27
Min: 10
Daylight saving: 0


I know the file was created at 11:25am on the 12th Nov 2013, the readings are for 11:10 to 11:25 with the last one in the file being the 11:10am one.

The mins match those in the file I get 10 through 25 in 5 min increments. The day is also accurate if I run it against other files.

There's a chance that the equipment manufacturer who wants us to purchase some expensive software to do this parsing has munged the timetamp specification but that being an option I've played with lots of possible combinations in that 32bit integer and I can't see how I can get all the numbers I require from the supplied timestamps.

Answer

I've found a C code and converted it to PHP. The results are a bit different but also obviously wrong. But perhaps that helps you.

The C code you find here. Search for Compound CP32. (There are no line numbers)

$hex = 0x2DAC1B0A;
$dt0 = $hex & 0xff;
$dt1 = ($hex >> 8) & 0xff;
$dt2 = ($hex >> 16) & 0xff;
$dt3 = ($hex >> 24) & 0xff;

$min = $dt0 & 0x3F;
$hour  = $dt1 & 0x1F;
$day  = $dt2 & 0x1F;
$mon   = ($dt3 & 0x0F) - 1;
$year  = (($dt2 & 0xE0) >> 5) | (($dt3 & 0xF0) >> 1);
$dayLightSaving = ($dt1 & 0x80) ? 1 : 0;

echo $min.'<br>'; // 10
echo $hour.'<br>'; // 27
echo $day.'<br>'; // 12
echo $mon.'<br>'; // 12
echo $year.'<br>'; // 21
echo $dayLightSaving; // 0