<?php
$attendance = [
"2019-07-01 08:00:00",
"2019-07-01 12:00:00",
"2019-07-01 13:00:00",
"2019-07-01 17:00:00",
];
/** TEST CASES:
// Late
$attendance = [
"2019-07-01 08:35:00",
"2019-07-01 12:00:00",
"2019-07-01 13:00:00",
"2019-07-01 17:00:00",
];
// Early
$attendance = [
"2019-07-01 07:45:00",
"2019-07-01 12:00:00",
"2019-07-01 13:00:00",
"2019-07-01 17:00:00",
];
*/
$schedules = [
[
"time_start" => "08:00:00",
"time_end" => "12:00:00",
"in_threshold" => 15,
"out_threshold" => 15
],
[
"time_start" => "13:00:00",
"time_end" => "17:00:00",
"in_threshold" => 15,
"out_threshold" => 15
]
];
// If date is between $from and $to
function isBetween( $from, $to, $date ) {
return ( $date > $from ) && ( $date <= $to );
}
// Get ClosestTime in schedules time_start and time_end
function getClosestTime( $array, $date ){
foreach( $array as $day ){
$interval[] = abs(strtotime($date) - strtotime($day));
}
asort($interval);
$closest = key($interval);
return $array[$closest];
}
// Store time_start and time_end to array
foreach($schedules as $schedule){
// Set time_start and time_end with threshold
$mytime_start[] = date( "H:i:s",
strtotime('+'. $schedule[ 'in_threshold' ] .' minutes',
strtotime ( $schedule[ 'time_start' ]
)));
$mytime_end[] = date( "H:i:s",
strtotime('+'. $schedule[ 'out_threshold' ] .' minutes',
strtotime( $schedule[ 'time_end' ]
)));
// Get time_start and time_end to array
$sched_starts[] = ( $schedule[ 'time_start' ] );
$sched_ends[] = ( $schedule[ 'time_end' ] );
}
// Initialized array
$total_garner_hours = 0;
$total_late = 0;
// Get attendance record by 2
for ($index = 0; $index < count($attendance); $index += 2) {
$date_start = $attendance[$index]; // Punch In
$date_end = $attendance[$index + 1]; // Punch Out
// Get Dates from time_in and time_out (for dates cross midnight)
$to_date_start = date("Y-m-d", strtotime($date_start));
$to_date_end = date("Y-m-d", strtotime($date_end));
// Get Closest time schedule
$time_start = getClosestTime($mytime_start, date('H:i:s',strtotime($date_start)));
$time_end = getClosestTime($mytime_end, date('H:i:s',strtotime($date_end)));
// Set check in to time start if its greater than time end
if ($time_start > $time_end) {
$time_start = date("Y-m-d", strtotime($date_start));
}
// Set date to datetime from $to_date_start / $to_date_end
$time_start = date('Y-m-d H:i:s', strtotime("$to_date_start $time_start"));
$time_end = date('Y-m-d H:i:s', strtotime("$to_date_end $time_end"));
// Remove threshold Eg. 08:15:00 to 08:00:00
$time_minus_start = date("Y-m-d H:i:s", strtotime("-15 minutes $time_start"));
$time_minus_end = date("Y-m-d H:i:s", strtotime("-15 minutes $time_end"));
// Sets variables to make it more readable
$within_in = $late = strtotime($date_start);
$within_out = $early = strtotime($date_end);
$exact_in = strtotime($time_minus_start);
$exact_out = strtotime($time_minus_end);
$late_out = strtotime($time_end);
// Check if date_start is Early or Exact
if ($date_start > $time_start) {
$start = $late;
$total_late += 1;
}else {
$start = $exact_in;
}
// Check if date_end is Early or Exact
($date_end < $time_end) ? $end = $early : $end = $exact_out;
// If date_start is between 08:00:00 and 08:15:00 and date_end is between 12:00:00 and 12:15:00
// return its date
if (isBetween($time_minus_start, $time_start, $date_start)
&& isBetween($time_minus_end, $time_end, $date_end)) {
$start = $within_in;
$end = $within_out;
} else if (isBetween($time_minus_start, $time_start, $date_start) && $date_end > $time_end) {
$start = $within_in;
$end = $late_out;
}
// Sum the total garnered hours
$total_garner_hours += ($end - $start);
}
$total_hours = floor($total_garner_hours / 3600);
echo ('Total Hours:'.$total_hours);
echo '<br>';
echo ('Late: '.$total_late);
preferences:
85.79 ms | 402 KiB | 5 Q