Система учета рабочего времени, как обрабатывать пользователя со сменой spesifi c с учетом времени входа? Laravel // PHP // Углерод - PullRequest
0 голосов
/ 16 апреля 2020

Система учета рабочего времени может иметь много смен.

Например:

Смена а) 08:00 - 16:00,

Смена б) 16:00 - 00:00,

Смена c) 00:00 - 08: 00,

Пользователь начинает работать в 07:55, как лучше всего сопоставить этого пользователя с правильным смещением, равным смещению a?

Имейте в виду, что система учета рабочего времени может иметь много смен гораздо ближе друг к другу, например, смену, которая начинается в 8:00, и смену, которая начинается в 9:00.

Важная информация: то, что я сделал, это foreach l oop, который сравнивает все начальные времена смен (в нашем примере 09:00, 16:00, 00:00) со временем, когда пользователь начал работать. В нашем примере 7:55. То, что ближе к рабочему времени пользователей, - это правильный сдвиг.

Это выглядит нормально, но на самом деле это не так. Причина в том, что, когда время около 00:00:00, а время смен не имеет даты, когда сравнение составляет 23:59:59 и 00:00:01, я получаю 86400 секунд вместо 2 секунд. Кроме того, вы никогда не знаете, какая дата больше другой, потому что пользователь может прийти раньше на работу или поздно.
Так что любые идеи должны учитывать это.

Спасибо за усилия

1 Ответ

0 голосов
/ 16 апреля 2020

Я обновил ответ на основе комментария, но в вопросе недостаточно информации, чтобы показать вам, как запрашивать базу данных и преобразовывать сдвиги в массив, который я использую в этом примере.

Этот кодовый блок является ссылкой, а не кодом для использования. Это массив времени запуска, в который нужно преобразовать таблицу базы данных.

$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 ()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...