Changes to timew() and wtime() to leverage last 2 bits for 4 year timestamp, making msgid checking valid according to FTSC. Added a test suite for timew()/wtime().

This commit is contained in:
2023-12-07 12:07:11 +11:00
parent ee15274478
commit fa2e74eaca
2 changed files with 89 additions and 7 deletions

View File

@@ -103,17 +103,18 @@ if (! function_exists('timew')) {
* are unique using 1/10th second precision.
*
* Time is:
* + 02 bits unused
* + 02 bits least significant bits of year - giving us a 4 year timestamp
* + 04 bits Month
* + 05 bits Day
* + 05 bits Hour
* + 06 bits Min
* + 06 bits Sec
* + 04 bits 10th Sec
* = 32 (2 bits free)
* = 32 bits
*
* @param Carbon|null $time
* @return int
* @todo Since this is used as part of our msgid, we need to use the first 2 bits to get our 3 year unique msgid, ie: year&0x03
*/
function timew(Carbon $time=NULL): int
{
@@ -130,19 +131,30 @@ if (! function_exists('timew')) {
$delay = $time->getPreciseTimestamp(1);
$t = ($time->month & 0xf) << 5;
$t = 0;
$t = ($t | $time->year & 0x3) << 4;
$t = ($t | ($time->month & 0xf)) << 5;
$t = ($t | ($time->day & 0x1f)) << 5;
$t = ($t | ($time->hour & 0x1f)) << 6;
$t = ($t | ($time->minute & 0x3f)) << 6;
$t = ($t | ($time->second & 0x3f));
$t = ($t | ($time->second & 0x3f)) << 4;
$t = ($t | ((int)($time->milli/100)) & 0xf);
return hexdec(sprintf('%07x%1x',$t,(round($time->milli/100) & 0x7f)));
return $t;
}
}
if (! function_exists('wtime')) {
/**
* Convert a 40 bit integer into a time.
* We need to filter out loose bits, ie:
* + year all bits valid
* + month 11xx and 0000 are invalid
* + day all bits valid except 0000
* + hour 11xxx are invalid
* + min 1111xx are invalid
* + sec 1111xx are invalid
* + 1/2 11xx, 101x are invalid
* @see timew()
*
* @param int $time
@@ -158,25 +170,36 @@ if (! function_exists('wtime')) {
if ($time > pow(2,26)-1) {
$milli = ($time & 0xf);
$time = $time >> 4;
if ($milli > 9)
$milli = 9;
} else {
$milli = 0;
}
$sec = ($time & 0x3f);
if ($sec > 59)
$sec = 59;
$time = $time >> 6;
$min = ($time & 0x3f);
if ($min > 59)
$min = 59;
$time = $time >> 6;
$hr = ($time & 0x1f);
if ($hr > 23)
$hr = 23;
$time = $time >> 5;
$day = ($time & 0x1f);
$time = $time >> 5;
$month = ($time & 0x1f);
$month = ($time & 0xf);
if ($month > 12)
$month = 12;
$time = $time >> 4;
return Carbon::create($year,$month,$day,$hr,$min,$sec+$milli/10);
return Carbon::create(($year & 0xffc)+$time,$month,$day,$hr,$min,$sec+$milli/10);
}
}