Я обновил ответ на основе комментария, но в вопросе недостаточно информации, чтобы показать вам, как запрашивать базу данных и преобразовывать сдвиги в массив, который я использую в этом примере.
Этот кодовый блок является ссылкой, а не кодом для использования. Это массив времени запуска, в который нужно преобразовать таблицу базы данных.
$shift_starts = [
// 1 represents the ID of the shift in your database.
1 => [
// Shift ID 1 starts at midnight, hour 0, minute 0
[0, 0],
],
// 2 represents the ID of the shift in your database.
2 => [
// Shift ID 2 starts at 8am, hour 8, minute 0
[8, 0],
],
// 3 represents the ID of the shift in your database.
3 => [
// Shift ID 3 starts at 4pm, hour 16, minute 0
[16, 0],
],
];
Создайте функцию, что-то вроде этого. Опять же, я не знаю, как вы запрашиваете ни свою базу данных, ни схему. Я просто знаю, как вы сохраняете время начала:
// Psudeo Code!!! Study and write your own function that returns
// the array as defined above.
function get_shift_start_array() {
$shift_starts = [];
$result = mysqli_query($db, "SELECT * FROM shifts ORDER BY start_time");
while ($row = mysqli_fetch_row($result)) {
// If the start_time is formatted h:m:s, then make it so you can get hours
// and minutes into their own variables:
$arr = explode(':', $row['start_time']);
$hour = $arr[0];
$minute = $arr[1];
$shift_starts[$row->id] = [$hour, $minute];
}
return $shift_starts;
}
Теперь, когда у нас есть способ перевести ваши данные смены в формат, который мы можем кодировать, эта функция примет отметку времени unix и возвратит идентификатор базы данных смены. (Обратите внимание, что эта функция вызывает вышеуказанную функцию)
Прочитайте комментарии и изучите функции PHP, которые вы, возможно, не понимаете.
/**
* Get the shift ID for a specific time.
*
* @param int $punchin_time Unix timestamp Default is the current time.
* @return int The shift id (the array key from $shift_starts)
*/
function findShift($punchin_time = null): int
{
if ($punchin_time === null) {
$punchin_time = time();
}
// Call the psudo code function to get an array of shift start times keyed by shift id.
$shift_starts = get_shift_start_array();
// Set $day to the unix timestamp of midnight yesterday.
$day = strtotime(date('Y-m-d', $punchin_time - 86400));
// We'll be checking the difference between punchin time and the shift time.
// $last_diff will be used to compare the diff of the current shift to the last shift.
// Initialize this with an arbitrarily high value beyond the 3 days we're looking at.
$last_diff = 86400 * 5; //
$last_index = null;
// Loop over 3 days starting with yesterday to accommodate punchin times before midnight.
// Return the shift ID when we find the smallest difference between punchin time and shift start.
for ($i = 0; $i <= 3; $i++) {
// Get the month, day, and year numbers for the day we are iterating on.
// We will use these in our calls to mktime()
$m = date('n', $day);
$d = date('j', $day);
$y = date('y', $day);
// Loop over each shift.
foreach ($shift_starts as $index => $start) {
// Create a unix timestamp of the shift start time.
// This is the date and time the shift starts based on the day iteration.
$time = mktime($start[0], $start[1], 0, $m, $d, $y);
// Get the difference in seconds between this shift start time and the punchin time.
$diff = abs($punchin_time - $time);
// $diff should be getting smaller as we get closer to the actual shift.
if ($diff > $last_diff) {
// If $diff got bigger than the last one, we've past the shift.
// Return the index of the last shift.
return $last_index;
}
$last_index = $index;
$last_diff = $diff;
}
$day = strtotime('+1 day', $day);
}
// Return null if no shift found.
return null;
}
Теперь, когда функции определены, вам просто нужно вызовите последний, чтобы преобразовать указанное c время в смену.
$punchin_time = mktime(15, 55, 0, 4, 15, 2020);
$shift_id = findShift($punchin_time);
В качестве альтернативы, не передавайте время, и будет использовано текущее время.
$shift_id = findShift($punchin_time);
mktime strtotime () DateTime :: getTimestamp ()