sql >> Base de Datos >  >> RDS >> Mysql

Usando PHP Carbon, elimine el tiempo en segundos donde dos períodos de tiempo se superponen

Lo que puede hacer es hacer un DatePeriod de intervalos de 1 segundo (supongo que esto es crítico para el negocio, por lo que tiene que ser al segundo) y verifique si cada segundo está dentro del horario comercial del día. Si es así, réstelo del total.

Sin embargo, esto es terriblemente ineficiente. Por ejemplo, solo por un día completo tendrías que hacer 86400 cheques. Se vuelve lento rápidamente . Tal vez, en su lugar, pueda usar un intervalo de 1 minuto o incluso de 1 hora si los requisitos de su negocio lo permiten, y hacer algunas estimaciones. De todos modos, así es como puedes hacer esto:

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

No menciona si los fines de semana son o no días hábiles para usted. Si lo son, simplemente verifique si el día actual en la iteración es sábado o domingo y reste todos esos segundos.

Puede hacer muchas optimizaciones aquí (almacenar en caché el día, por ejemplo), pero debería llevarlo en la dirección correcta.

(No puedo mostrarte una demostración porque no puedo use Carbon en los proveedores típicos)