Добавление интервалов DateTime с циклом foreach - PullRequest
2 голосов
/ 06 июня 2019

Я вчера задал вопрос по суммированию интервалов даты и времени, и мне указали на эту ветку - Как мы можем добавить два интервала дат в PHP

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

Это функция, которую я сделал, которая получает все часы времени и времени сотрудников, они хранятся вБД и создаются с использованием даты php (H: i: s).

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

Я пытался добиться этого, конвертируя время в объекты datetime и используя -> diff для получения интервалов и, таким образом, вычисляя эти дни, я пытаюсь использовать цикл foreach для добавленияинтервалы вместе, что дает мне общее количество часов, отработанных в любом заданном диапазоне дат.

Вся функция вместе состоит в следующем:

function getTotalHours($staff_id,$from_date,$to_date){

    $sql = "SELECT * FROM oc_staff_times WHERE date BETWEEN '$from_date' AND '$to_date' AND staff_id = '$staff_id'";
    $result = $this->conn->query($sql);

    if ($result->num_rows > 0) {
        while ($row = mysqli_fetch_assoc($result)) {
            $data[] = $row;
        }

        $base_time = new DateTime('00:00');
        $total = new DateTime('00:00');

        foreach ($data as $time) {
            $in = new DateTime($time['clock_in_time']); 
            $out = new DateTime($time['clock_out_time']); 
            $interval = $in->diff($out);
            $base_time->add($interval); 
        }

        return $total->diff($base_time)->format("%H:%I");       
    }
}

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

1

Ответы [ 2 ]

1 голос
/ 06 июня 2019

Ответ от Qirel предлагает хороший способ сделать это в SQL, однако, если вы хотите понять, почему ваш код не работал:

$base_time = new DateTime('00:00'); не создает интервал, это дата.Это означает, что если вы добавите к нему 24 часа и зададите только часть времени, будет показано «00: 00», потому что вы окажетесь на следующий день позже.

Одним из решений было бы объявить $base_time какинтервал, например, такой: $base_time = new DateInterval('PT0S');

И в конце выведите прямо так: $base_time->format("%H:%I");

1 голос
/ 06 июня 2019

Вы можете сделать это одним запросом.Используйте TIMEDIFF(), чтобы получить разницу для каждой строки, затем преобразуйте их в секунды, используя TIME_TO_SEC(), SUM(), и переведите их в формат времени с SEC_TO_TIME() - все в MySQL!

SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(TIMEDIFF(`clock_out_time`, `clock_in_time`))))
FROM `oc_staff_times`
WHERE `staff_id` = ?
  AND `date` BETWEEN ? AND ?

Создание вашей функции с подготовленным оператором ..

function getTotalHours($staff_id, $from_date, $to_date){
    $sql = "SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(TIMEDIFF(`clock_out_time`, `clock_in_time`))))
            FROM `oc_staff_times`
            WHERE `staff_id` = ?
              AND `date` BETWEEN ? AND ?";

    $stmt = $this->conn->prepare($sql);
    $stmt->bind_param("sss", $staff_id, $from_date, $to_date);
    $stmt->execute();
    $stmt->bind_result($totalTime);
    $stmt->fetch();
    $stmt->close();
    return $totalTime;   
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...