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

Stop execution till the beginning of the next hour

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

Number of microseconds must be greater than or equal to 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);

在您的情况下,您的时基不是微秒,而是 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);

既然你需要比秒更高的精度,那么我认为我们需要同时使用它们。
首先我们等待几秒钟直到我们关闭然后我们计算微秒并再次等待。

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