I have these datetime input in array from 8am until 5pm
2022-09-23 08:00:00
2022-09-23 08:30:00
2022-09-23 09:00:00
2022-09-23 09:30:00
2022-09-23 10:00:00
2022-09-23 10:30:00
2022-09-23 11:00:00
2022-09-23 13:00:00
2022-09-23 13:30:00
2022-09-23 14:00:00
2022-09-23 14:30:00
2022-09-23 15:00:00
2022-09-23 16:00:00
2022-09-23 16:30:00
2022-09-23 17:00:00
2022-09-23 17:30:00
My goal is to get/output previous array if input for datetime is greater than previous array and less than next array
Input datetime 2022-09-23 09:12:00, it will use 2022-09-23 09:00:00
Input datetime 2022-09-23 10:29:00, it will use 2022-09-23 10:00:00
My current code:
$final_datetime = array();
$datetime = "2022-09-22 09:12:00";
foreach ($arr as $k => $v) {
if ($v == $datetime) {
$final_datetime[] = $v;
} else {
$next1="";
$prev1="";
// Previous Array
if (isset($arr[$k-1])) {
$prev1 = $arr[$k-1];
}
// Next Array
if (isset($arr[$k+1])) {
$next1 = $arr[$k+1];
}
$prev2 = date_create($prev1);
$prev = date_format($prev2, 'Y-m-d H:i:s');
$next2 = date_create($next1);
$next = date_format($next2, 'Y-m-d H:i:s');
if ($datetime > $prev && $datetime < $next) {
echo 'Output : '.$prev.'<br/>';
} else {
}
}
}
My current output:
Output : 2022-09-22 08:30:00
Output : 2022-09-22 09:00:00
Expected Output:
Output : 2022-09-22 09:00:00
Using date_format returns a string, but you want to compare DateTime objects for the given format 'Ymd H:i:s'
A few notes about the code.
2022-09-23
in the array, but the variable $datetime = "2022-09-22 09:12:00";
is of the day beforePrevious Array
while you actually mean the previous array item$final_datetime
or make $final_datetime
a string and overwrite the value everytime there is a new match. As you are using only a single value to check and the timeslots in sequence, you can just overwrite the valueExample code
$datetimeStr = "2022-09-23 09:12:00";
$final_datetime = "$datetimeStr is not within timeslots.";
$format = 'Y-m-d H:i:s';
$d = DateTime::createFromFormat($format, $datetimeStr);
foreach ($arr as $k => $v) {
if ($v === $datetimeStr) {
$final_datetime = $v;
break;
} else {
$prevDatetime = false;
$nextDateTime = false;
$prevStr = "";
$nextStr = "";
if (isset($arr[$k - 1])) {
$prevStr = $arr[$k - 1];
}
if (isset($arr[$k + 1])) {
$nextStr = $arr[$k + 1];
}
if ($prevStr) {
$prevDatetime = DateTime::createFromFormat($format, $prevStr);
}
if ($nextStr) {
$nextDateTime = DateTime::createFromFormat($format, $nextStr);
}
if ($prevDatetime && $nextDateTime && $d && ($d > $prevDatetime && $d < $nextDateTime)){
$final_datetime = $prevStr;
}
}
}
echo "Output: " . $final_datetime;
Result
Output: 2022-09-23 09:00:00
See a php demo .
You were on the right track using date_create()
, the easiest way is to just add the input datetime to the array and convert everything into a DateTime
with array_map()
then pass it to sort()
. Then all you have to do is search the array for the input DateTime
. If it is the first or last item in the array that means its outside the range. Below, I wrote the process into a function that returns false
if the datetime falls outside the range (btw, your example searches for a datetime outside the range).
function findTimeSlotFor(string $dt_str, array $ts_arr)
{
if (in_array($dt_str, $ts_arr))
// return exact string match
return $dt_str;
// add it to the array
$ts_arr[] = $dt_str;
// convert to DateTimes
$dt_arr = array_map('date_create', $ts_arr);
$dt = date_create($dt_str);
// sort the array
sort($dt_arr);
// find where it landed
$landed_at_index = array_search($dt, $dt_arr);
if(0 == $landed_at_index || array_key_last($dt_arr) == $landed_at_index){
// input datetime outside the range of datetimes in the array
// adjust to your logic
return false;
}
// return the one before
return $dt_arr[$landed_at_index - 1]->format('Y-m-d H:i:s');
}
See the above code in action here: https://onlinephp.io/c/2cc7a
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.