停止执行直到下一个小时开始

时间:2019-06-16 11:40:13

标签: php date microtime usleep

我成功地找到了(我认为)直到下一个小时开始要经过多少微秒,但是usleep()函数显示警告

  

微秒数必须大于或等于0

$min = (integer)date('i');
$sec = (integer)date('s');
list($microsec, $tmp) = explode(' ', microtime());
$microsec = (integer)str_replace("0.", "", $microsec);
$min_dif = 59 - $min;
$sec_dif = 59 - $sec;
$microsec_dif = 100000000 - $microsec;
$dif_in_micro = $sec_dif * 100000000 + $min_dif * 6000000000 + 
$microsec_dif;
echo $dif_in_micro;
usleep($dif_in_micro);

非常感谢您的回答,我最终使用以下内容

$seconds_to_wait = 3540 - (integer)date('i') * 60 + 59 - (integer)date('s');
list($microsec, $tmp) = explode(' ', microtime());
$microsec_to_wait = 1000000 - $microsec * 1000000;
sleep($seconds_to_wait);
usleep($microsec_to_wait);
$now = DateTime::createFromFormat('U.u', microtime(true));
file_put_contents("finish_time.txt", $now->format("m-d-Y H:i:s.u") . PHP_EOL, FILE_APPEND);

2 个答案:

答案 0 :(得分:1)

由于您需要比秒更高的精度,所以我认为我们需要同时使用它们。
首先,我们等待秒,直到接近,然后计算微秒,然后再次等待。

$Seconds = (microtime(true) - 3600*floor(microtime(true)/3600))-2;
sleep(3600 - $Seconds);
//Code above should wait until xx:59:58
// Now your code should just work fine below here except we shouldn't need minutes

$sec = (integer)date('s');
list($microsec, $tmp) = explode(' ', microtime());
$microsec = (integer)str_replace("0.", "", $microsec);
$sec_dif = 59 - $sec;
$microsec_dif = 100000000 - $microsec;
$dif_in_micro = $sec_dif * 100000000  + $microsec_dif;
echo $dif_in_micro;
usleep($dif_in_micro);

答案 1 :(得分:0)

在您的情况下,您的时基不是微秒,而是10ns分辨率。

microtime()以秒为单位提供8位小数的时间。您正在剥离前导0。并使用八个小数。您通过编写$microsec_dif = 1E8 - $microsec;来考虑这一点。您将结果发送到usleep(),而不补偿100的因数。这使您的超时时间是预期值的100倍。整数溢出可能排在最前面。

usleep的时间为整数。最大值约为2E9 µs。受此限制,您不能为单个呼叫等待超过2000秒的时间。

这是我的代码:

$TimeNow=microtime(true);
$SecondsSinceLastFullHour = $TimeNow - 3600*floor($TimeNow/3600);
//echo ("Wait " .   (3600 - SecondsSinceLastFullHour) . " seconds.");
$Sleeptime=(3600.0 - $SecondsSinceLastFullHour); //as float
//Maximum of $Sleeptime is 3600    
//usleep(1e6*$Sleeptime); //worst case 3600E6 won't fit into integer.
//...  but 1800E6 does. So lets split the waiting time in to halfes.
usleep(500000*$Sleeptime);
usleep(500000*$Sleeptime);