Carbon difference between two dates to get a decimal for hourly rate calculations

Viewed 13030

I am using Carbon to calculate the time between two dates. I'd like to be able to take difference between two dates and determine the time in decimal format to be able to calculate hourly rate. From my testing, the ->diffInHours() call gives me the hours between two dates in whole numbers.

For example

$actual_start_at = Carbon::parse('2017-05-01 13:00:00');
$actual_end_at = Carbon::parse('2017-05-01 15:15:00');
return $actual_end_at->diffInHours($actual_start_at, true);

Returns

2

I would like something that returns to get the 2 hours 15 minutes

2.25
3 Answers

Here's a more complete solution using CarbonPeriod.

Carbon Calculate hours in an interval from a period

<?php

use Carbon\Carbon;
use Carbon\CarbonPeriod;
use Carbon\CarbonInterval;

class PeriodInterval {
    public function hoursIn() {
        /**
        * Time Periods
        */
        $periods = [
            'day' => [
                '08:00:00',
                '18:00:00'
            ],
            'night' => [
                '18:00:00',
                '08:00:00'
            ],
            'lunch' => [
                '11:00:00',
                '14:00:00'
            ]
        ];

        /**
        * Time Intervals
        */
        $intervals = [
            'parking' => [
                'John Doe' => [
                    Carbon::createFromFormat('Y-m-d H:i:s', '2018-12-10 07:00:00'),
                    Carbon::createFromFormat('Y-m-d H:i:s', '2018-12-10 09:00:00')
                ],
                'Jane Doe' => [
                    Carbon::createFromFormat('Y-m-d H:i:s', '2018-12-10 08:00:00'),
                    Carbon::createFromFormat('Y-m-d H:i:s', '2018-12-10 09:00:00')
                ],
                'John Hope' => [
                    Carbon::createFromFormat('Y-m-d H:i:s', '2018-12-10 11:00:00'),
                    Carbon::createFromFormat('Y-m-d H:i:s', '2018-12-10 13:00:00')
                ],
                'Jane Hope' => [
                    Carbon::createFromFormat('Y-m-d H:i:s', '2018-12-10 18:00:00'),
                    Carbon::createFromFormat('Y-m-d H:i:s', '2018-12-10 19:00:00')
                ]
            ]
        ];

        /**
        * Hours for Interval in Period
        */
        function hoursForIntervalInPeriod(array $period, array $interval) {
            $Period = new CarbonPeriod(array_shift($interval)->toDateTimeString(), '1 hour', array_pop($interval)->toDateTimeString());

            return $Period->filter(function($date) use ($period) {
                $period_starts = Carbon::createFromFormat('Y-m-d H:i:s', $date->format('Y-m-d') . ' ' . array_shift($period));
                $period_ends = Carbon::createFromFormat('Y-m-d H:i:s', $date->format('Y-m-d') . ' ' . array_pop($period));

                // Normal Period
                if ($period_starts < $period_ends) {
                    return ($date >= $period_starts && $date < $period_ends);
                }

                // Inverted Period (Overnight)
                if ($period_starts > $period_ends) {
                    return ($date >= $period_starts || $date < $period_ends);
                }

                return false;
            })->count();
        }

        /**
        * Map Everything
        */
        $hours = array_map(function($interval, $interval_key) use ($periods) {
            return array_map(function ($period, $period_key) use ($interval, $interval_key) {
                return [ $interval_key . ucfirst($period_key) => array_map(function($interval_item, $interval_item_key) use ($period) {
                    /**
                    * Calculate Total Hours
                    */
                    $total_hours = hoursForIntervalInPeriod($period, $interval_item);

                    return [ $interval_item_key => $total_hours ];
                }, $interval, array_keys($interval)) ];
            }, $periods, array_keys($periods));
        }, $intervals, array_keys($intervals));

        return $hours;
    }
}

There is Carbon::floatDiffInDays() which should suit your needs

Related