I have a 2d array of jobs and each job contains a start time, an end time which is always 60 minutes after the start time, then an "add" value which is the number of minutes until the next job should start.
I need to adjust all rows so that each start time is the previous job’s end time plus its "add" time.
Here is a sample array:
[
[
'id' => 9,
'needed_at' => '2023-02-26 03:31:04',
'ended_at' => '2023-02-26 04:31:04',
'add' => 20
],
[
'id' => 6,
'needed_at' => '2023-02-26 04:51:04',
'ended_at' => '2023-02-26 05:51:04',
'add' => 30
],
[
'id' => 7,
'needed_at' => '2023-02-26 09:21:04',
'ended_at' => '2023-02-26 10:21:04',
'add' => 30
]
]
My desired result:
[
[
'id' => 9,
'needed_at' => '2023-02-26 03:31:04',
'ended_at' => '2023-02-26 04:31:04',
'add' => 20
],
[
'id' => 6,
'needed_at' => '2023-02-26 04:51:04',
'ended_at' => '2023-02-26 05:51:04',
'add' => 30
],
[
'id' => 7,
'needed_at' => '2023-02-26 06:21:04', # changed based on id 6 data
'ended_at' => '2023-02-26 07:21:04', # changed based on new need_at time of this row
'add' => 30 # not actually used because no next job
]
]
What I have tried is:
foreach ($jobs as $k => $j) {
$s = $k+1;
$date = new DateTimeImmutable($j->ended_at);
$add = $j->add;
$date_new = $date->modify('+'.$add.' minutes');
$needed_at = $date_new->format('Y-m-d H:i:s');
$data['needed_at'] = $needed_at;
$date2 = new DateTimeImmutable($needed_at);
$ended_at = $date2->modify('+60 minutes');
$data['ended_at'] = $ended_at->format('Y-m-d H:i:s');
$d[]=[
'id' => $jobs[$s]->id,
'needed_at' => $needed_at,
'ended_at' => $data['ended_at'],
'add' => $add
];
}
It is not working. Is it possible to use first iteration modified data into second iteration?
2
Answers
Since the first element of the array will not change we excluded from the loop.
Two elements are important to get the expected output :
ended_at
andadd
, then after each iteration those variables will take the current values and so onDemo here
For a direct and concise way to create contiguous datetime stamps across all rows in your data, use a single loop, modify the rows by reference, declare a single datetime object, then bump or save the the datetime stamp as needed.
There is no need to waste/double memory by building a completely new output array.
Code: (Demo)