我如何才能找到一天中确切的工作时间以及一天中的休息时间?

时间:2018-07-12 13:58:55

标签: php mysql laravel-5.2

我有给定时间的休息时间和工作时间,如何找到一天中确切的工作时间和一天中的休息时间?

工作时间输入是这样

enter image description here

以前,我以前只有一个场景,例如7月2日,那样的话我将休息时间转换为小时,并直接从工作时间中扣除。

$secondsPerHour = 3600;

// Getting break entries
$breakTimeEntries = TimeEntries::select('start_date', 'start_time', 'end_time', 'hour_type')
                               ->where('hour_type', 'break') 
                               ->orderBy('start_date')->get();

$breakDurationPerDayArray = array();
// Looping through all the break entries and getting the break entries for each day
foreach($breakTimeEntries as $breakTimeEntry) {
    $startDate = $breakTimeEntry->start_date;
    $breakStartTime = $breakTimeEntry->start_time;
    $breakEndTime = $breakTimeEntry->end_time;

    $breakHours = $breakEndTime - $breakStartTime;
    $breakHoursInSeconds = $breakHours/$secondsPerHour;

    // Adding the break entry for the day to array
    $breakTimePerDayArray[$startDate] = $breakHoursInSeconds;
}

// Getting work entries
$breakTimeEntries = TimeEntries::select('start_date', 'start_time', 'end_time', 'hour_type')
                               ->where('hour_type', 'work') 
                               ->orderBy('start_date')->get();

$workAndBreakHoursArray = array();                             
// Looping through all the work entries and getting the actual work entries for each day
foreach($breakTimeEntries as $breakTimeEntry) {                            
    $workStartTime = $workTimeEntry->start_time;
    $workEndTime = $workTimeEntry->end_time;

    $workHours = $workEndTime - $workStartTime;
    $workHoursInSeconds = $breakHours/$secondsPerHour;


    $startDate = $breakTimeEntry->start_date;

    // Checking wether the start date is in array
    if(in_array($startDate, $breakDurationPerDayArray)) {
        $breakHoursInSeconds = $breakDurationPerDayArray[$startDate];
        $actualWorkedHours = $workHoursInSeconds - $breakHoursInSeconds;
        //To get the worked hours in minutes
        $actualWorkedHoursInMins = $actualWorkedHours/$secondsPerHour;
        //To get the break hours in minutes
        $breakHoursInMin =  $breakHoursInSeconds/$secondsPerHour;
        $workAndBreakHoursArray[$startDate] = ['worked_hours' => $actualWorkedHoursInMins, 'break_hours' => $breakHoursInMin];
    } else {
        //To get the worked hours in minutes
        $workHoursInMins = $workHoursInSeconds/$secondsPerHour;
        $workAndBreakHoursArray[$startDate] = ['worked_hours' => $workHoursInMins, 'break_hours' => 0];
    }
}

此刻我没主意了。好的,有人建议最好的处理方法。

预期的产量以小时为单位

[
    [2018-07-02] => [Work => 8, Break =>1],
    [2018-07-03] => [Work => 8, Break =>1],
    [2018-07-04] => [Work => 8, Break =>1],
    [2018-07-05] => [Work => 3.5, Break =>0.5],
    [2018-07-06] => [Work => 4.5, Break =>0.5],
    [2018-07-09] => [Work => 3.5, Break =>0.5],
    [2018-07-10] => [Work => 4.5, Break =>0.5]
]

Database Fiddle Link

1 个答案:

答案 0 :(得分:1)

您标记了Laravel,所以我认为您正在使用它。 它包含Carbon,它是处理与时间相关的所有问题的好工具。 https://carbon.nesbot.com/docs/#Difference

Edit1:这是一个示例,还假设您对条目进行了标准化:

$entries = [
    [
        'type'  => 'work',
        'start' => 1310198400,
        'end'   => 1310230800,
    ],
    [
        'type'  => 'break',
        'start' => 1310212800,
        'end'   => 1310216400,
    ],
    [
        'type'  => 'work',
        'start' => 1310284800,
        'end' => 1310299200,
    ],
    [
        'type'  => 'break',
        'start' => 1310299200,
        'end' => 1310302800,
    ],
    [
        'type'  => 'work',
        'start' => 1310302800,
        'end' => 1310317200,
    ],
    [
        'type'  => 'work',
        'start' => 1310371200,
        'end' => 1310385600,
    ],
    [
        'type'  => 'break',
        'start' => 1310384700,
        'end' => 1310387400,
    ],
    [
        'type'  => 'work',
        'start' => 1310387400,
        'end' => 1310403600,
    ]
];

$workEntries = collect();
$breakEntries = collect();

foreach ($entries as $entry)
{
    if ($entry['type'] == 'work')
        $workEntries->push($entry);

    else if ($entry['type'] == 'break')
        $breakEntries->push($entry);
}

/*
    For each work entry, check if any break entry overlaps.
*/
foreach ($workEntries as $workEntry)
{
    $workStart  = $workEntry['start'];
    $workEnd    = $workEntry['end'];

    foreach ($breakEntries as $breakEntry)
    {
        $breakStart         = $breakEntry['start'];
        $breakEnd           = $breakEntry['end'];
        $overlapDuration    = 0;

        if (!Carbon::createFromTimestamp($workStart)->isSameDay(Carbon::createFromTimestamp($breakStart)))
            continue;

        /*
            Check if work and break overlap

            Scenario 1:
                Break started mid-work

            Scenario 2:
                Break started before work
        */
        if (($breakStart >= $workStart) || ($breakStart < $workStart))
        {
            if ($breakStart >= $workStart)
                $overlapStart = $breakStart;

            else if ($breakStart < $workStart)
                $overlapStart = $workStart;

            /*
                Break ends before work ends (or simultaneously)
            */
            if ($breakEnd <= $workEnd)
                $overlapEnd = $breakEnd;

            /*
                Break ends after work ends
            */
            else
                $overlapEnd = $workEnd;

            /*
                Calculate overlap length
            */
            $overlapDuration = $overlapEnd - $overlapStart;
        }

        /*
            Actual time worked that day is time worked - breaks that overlap work periods.
            Get human-friendly date (day, month, year), display.
        */
        $workDuration = ($workEnd - $workStart - $overlapDuration)/3600;
        $date = Carbon::createFromTimestamp($workStart)->toFormattedDateString();

        dump("Time worked on $date is $workDuration h.");
    }
}

将打印:

"Time worked on Jul 9, 2011 is 8 h."
"Time worked on Jul 10, 2011 is 4 h."
"Time worked on Jul 10, 2011 is 4 h."
"Time worked on Jul 11, 2011 is 3.75 h."
"Time worked on Jul 11, 2011 is 4.5 h."

我认为将每天的数据分组不会造成太大麻烦:)

Edit2:在制作示例之前,我没有注意到您更改了问题,因此请原谅数据不会以您想要的格式显示。同样,使它适合您的需求应该很容易。