so basic steps are:
- group data by user
- group each user data by day
- calculations on grouped by day timestamps
/**
* helper function for data sample
* credits https://stackoverflow.com/a/24431558/6330083
* @param DateTime $start
* @param DateTime $end
* @return DateTime
*/
function randomDateInRange(DateTime $start, DateTime $end)
{
$randomTimestamp = mt_rand($start->getTimestamp(), $end->getTimestamp());
$randomDate = new DateTime();
$randomDate->setTimestamp($randomTimestamp);
return $randomDate;
}
/**
* provides basic raw data sample
* example output
* [
* [
* "first-name" => "0",
* "last-name" => "00",
* "time" => "2022-05-01 15:43:22",
* ],
* [
* "first-name" => "0",
* "last-name" => "00",
* "time" => "2022-05-02 13:43:06",
* ],
* [
* "first-name" => "1",
* "last-name" => "11",
* "time" => "2022-05-01 16:15:27",
* ],
* ...
* ]
* @return array
*/
function sampleData()
{
$dateStart = new DateTime('2022-05-01');
$dateEnd = (new DateTime())->setTimestamp($dateStart->getTimestamp());
$dateEnd->add(DateInterval::createFromDateString('2 days'));
$sample = [];
for ($i = 0; $i < 10; $i++) {
for ($k = 0; $k < random_int(0, 6); $k++) {
$time = randomDateInRange($dateStart, $dateEnd)->format('Y-m-d H:i:s');
array_push($sample, [
'first-name' => "$i",
'last-name' => "$i$i",
'time' => $time
]);
}
}
return $sample;
}
/**
* @param array
* @return array
*/
function calculateWorkingHours(array $data = [])
{
if (count($data) == 0) {
$data = sampleData();
}
/* at this step we're grouping data by user with subarray contains time column
sample output
[
"1 11" => [
"2022-05-02 13:44:10",
],
"2 22" => [
"2022-05-02 03:59:20",
"2022-05-02 17:50:01",
],
...
]
*/
$grouped = [];
foreach ($data as $row) {
$groupName = $row['first-name'] . " " . $row['last-name'];
$grouped[$groupName][] = $row['time'];
}
/*
next groping by day
actually this step probably might be changed to make final
summary instead of grouping,
but you didn't mention the way you should calculate working
hours from provided timestamps
sample output
[
"0 00" => [
"2022-05-01" => [
"2022-05-01 13:01:14",
"2022-05-01 19:02:24",
],
"2022-05-02" => [
"2022-05-02 07:54:44",
],
],
"1 11" => [
"2022-05-02" => [
"2022-05-02 05:10:19",
"2022-05-02 14:40:41",
],
"2022-05-01" => [
"2022-05-01 12:15:36",
"2022-05-01 23:26:19",
],
],
...
]
*/
$withGroupedTimes = array_map(function ($ungroupedTimes) {
$gropedTimes = [];
foreach ($ungroupedTimes as $time) {
$day = (new DateTime($time))->format('Y-m-d');
$gropedTimes[$day][] = $time;
}
return $gropedTimes;
}, $grouped);
// now we have structure grouped by user with subroups by day for
// each user and can provide calculations
$calculated = array_map(function ($user) {
return array_map(function ($day) {
// $day is array of timestamps
// here you should provide logic to sum hours and return it int $result variable
// as a basic example i return intervals count of that day
$result = count($day);
return $result;
}, $user);
}, $withGroupedTimes);
return $calculated;
}