1

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
1
  • Just loop the array in reverse order. When $datetime is >= the current array element, output it and break out of the loop at that point. Commented Sep 23, 2022 at 7:17

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

Comments

0

Using date_format returns a string, but you want to compare DateTime objects for the given format 'Y-m-d H:i:s'

A few notes about the code.

  • You are using 2022-09-23 in the array, but the variable $datetime = "2022-09-22 09:12:00"; is of the day before
  • It can be confusing to put in the comment Previous Array while you actually mean the previous array item
  • If you only want to return a single item, then you should either return the last item of the array $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 value
  • At the end of the code when doing the comparison for the datetimes, you can first check the values of the variables that are in scope

Example 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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.