Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Usando PHP Carbon, remova o tempo em segundos onde dois períodos de tempo se sobrepõem


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)