O que você pode fazer é criar um
DatePeriod
intervalos de 1 segundo (presumo que isso seja crítico para os negócios, portanto, deve ser para o segundo) e verifique se cada segundo está dentro do horário comercial do dia. Se for, subtraia do total. Isso é terrivelmente ineficiente, no entanto. Por exemplo, apenas para um dia inteiro você teria que fazer 86.400 cheques. Fica lento rapidamente . Talvez você possa usar um intervalo de 1 minuto ou até 1 hora, se seus requisitos de negócios permitirem, e fazer algumas estimativas. De qualquer forma, é assim que você pode fazer isso:
<?php
use Carbon\Carbon;
$startTime = Carbon::create(2017, 9, 10, 8, 20, 0);
$endTime = Carbon::create(2017, 9, 10, 18, 35, 0);
$duration = $startTime->diffInSeconds($endTime, true);
$interval = new DateInterval("PT1S");
$period = new DatePeriod($startTime, $interval, $endTime);
$secondsToSubtract = 0;
foreach ($period as $second) {
$businessStart = clone $second;
$businessStart->setTime(8, 0); // start business day
$businessEnd = clone $second;
$businessEnd->setTime(17, 0); // end business day
if (!($second > $businessStart && $second < $businessEnd)) { // if the second is not a "business second", subtract it
$secondsToSubtract++;
}
}
var_dump($secondsToSubtract);
$realDuration = $duration - $secondsToSubtract;
var_dump($realDuration);
Você não menciona se os fins de semana são ou não são dias úteis para você. Se forem, apenas verifique se o dia atual na iteração é sábado ou domingo e subtraia todos esses segundos.
Você pode fazer muitas otimizações aqui (armazenando em cache o dia, por exemplo), mas isso deve levá-lo na direção certa.
(Não posso mostrar uma demonstração porque não posso
use Carbon
nos provedores típicos)