【问题标题】:Carbon difference between two dates to get a decimal for hourly rate calculations两个日期之间的碳差以获得小时费率计算的小数
【发布时间】:2017-10-21 15:23:38
【问题描述】:

我正在使用 Carbon 来计算两个日期之间的时间。我希望能够获取两个日期之间的差异并确定十进制格式的时间,以便能够计算小时费率。根据我的测试, ->diffInHours() 调用以整数形式为我提供了两个日期之间的小时数。

例如

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

返回

2

我想要返回得到2 hours 15 minutes的东西

2.25

【问题讨论】:

    标签: php date laravel-5 diff php-carbon


    【解决方案1】:

    很遗憾,diffInHours 只接受两个参数。也许,您可以尝试diffInMinutes,然后从那里获取您需要的值?

    例如

    $actual_start_at = Carbon::parse('2017-05-01 13:00:00');
    $actual_end_at   = Carbon::parse('2017-05-01 15:15:00');
    $mins            = $actual_end_at->diffInMinutes($actual_start_at, true);
    
    dd($mins/60);
    

    会输出

    2.25
    

    另外,如果你使用diff() 方法,它会返回一个DateInterval 对象。

    $mins = $actual_end_at->diff($actual_start_at, true);
    

    然后dd($mins) 会输出:

    DateInterval {#913 ▼
      +"y": 0
      +"m": 0
      +"d": 0
      +"h": 2
      +"i": 15
      +"s": 0
      +"f": 0.0
      +"weekday": 0
      +"weekday_behavior": 0
      +"first_last_day_of": 0
      +"invert": 0
      +"days": 0
      +"special_type": 0
      +"special_amount": 0
      +"have_weekday_relative": 0
      +"have_special_relative": 0
    }
    

    【讨论】:

    • 当然,解决方法就是这么简单。我不敢相信我没想过要走这条路。感谢您的回复。
    • @jdcarg 如果它对您有用,请您接受答案吗? :)
    【解决方案2】:

    这是使用 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;
        }
    }
    

    【讨论】:

      【解决方案3】:

      Carbon::floatDiffInDays() 应该能满足你的需求

      【讨论】:

      • 使用时获取BadMethodCallException with message 'Method floatDiffInDays does not exist.'
      猜你喜欢
      • 2021-10-09
      • 2020-02-08
      • 1970-01-01
      • 1970-01-01
      • 2012-10-26
      • 1970-01-01
      • 2016-10-06
      相关资源
      最近更新 更多