Остановите выполнение до начала следующего часа - PullRequest
0 голосов
/ 16 июня 2019

Я успешно нахожу (я думаю), сколько микросекунд должно пройти до начала следующего часа, но функция 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 ]

1 голос
/ 16 июня 2019

Поскольку вам нужна более высокая точность, чем дает секунда, я думаю, что нам нужно использовать их обе.
Сначала мы ждем секунд, пока мы не приблизимся, затем мы вычисляем микросекунды и ждем снова.

$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);
0 голосов
/ 16 июня 2019

В вашем случае ваша временная база не микросекунды, а разрешение 10 нс

microtime () выдает время в секундах с 8 десятичными знаками. Вы удаляете ведущий 0. и используете восемь десятичных знаков. Вы рассмотрели это, написав $microsec_dif = 1E8 - $microsec;. Вы отправляете результат в usleep (), без компенсации коэффициента 100. Это дает вам время ожидания в 100 раз больше, чем вы предполагали. И целочисленное переполнение может прийти сверху.

usleep занимает целое время. Максимум составляет около 2E9 мкс. С этим ограничением вы не можете ждать более 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);
...