Untitled

mail@pastecode.io avatar
unknown
php
7 months ago
1.9 kB
1
Indexable
Never
private function calculateTimeSpentPerDay($intervals)
{
    $days = [];

    foreach ($intervals as $interval) {
        $start = Carbon::parse($interval['start']);
        $end = Carbon::parse($interval['end']);
        $this->constrainIntervalToCurrentMonth($start, $end);

        if ($start->isSameDay($end)) {
            $this->accumulateTimeForSingleDay($start, $end, $days);
        } else {
            $this->accumulateTimeForMultipleDays($start, $end, $days);
        }
    }

    return $days;
}

private function constrainIntervalToCurrentMonth(&$start, &$end)
{
    $start = max($start, $this->month->startOfMonth());
    $end = min($end, $this->month->endOfMonth());
}

private function accumulateTimeForSingleDay($start, $end, &$days)
{
    $dayString = $start->toDateString();
    $current = $days[$dayString] ?? 0;
    $days[$dayString] = $current + $end->diffInSeconds($start);
}

private function accumulateTimeForMultipleDays($start, $end, &$days)
{
    $periodDate = $start->copy()->startOfDay();
    $newEnd = $end->copy()->endOfDay();

    while ($periodDate->lt($newEnd)) {
        $this->accumulateTimeForSpecificDay($periodDate, $start, $end, $days);
        $periodDate->addDay();
    }
}

private function accumulateTimeForSpecificDay($periodDate, $start, $end, &$days)
{
    $current = $days[$periodDate->toDateString()] ?? 0;
    $timeDifferenceInSeconds = $this->calculateTimeDifferenceInSeconds($periodDate, $start, $end);

    $days[$periodDate->toDateString()] = $current + $timeDifferenceInSeconds;
}

private function calculateTimeDifferenceInSeconds($periodDate, $start, $end)
{
    if ($periodDate->isSameDay($start)) {
        return $start->diffInSeconds($start->endOfDay());
    }

    if (!$periodDate->isSameDay($end)) {
        return $periodDate->startOfDay()->diffInSeconds($periodDate->endOfDay());
    }

    return $periodDate->startOfDay()->diffInSeconds($end);
}