Как преобразовать секунды в формат Час:Минута:Секунда в PHP?
Решение с помощью деления и форматирования
Ваша основная ошибка в том, что при делении вы получаете дробные числа, так как оператор / в PHP возвращает float. Вам нужно использовать целочисленное деление (intdiv) или явно приводить результат к int. Также для красивого вывода с ведущими нулями удобно использовать функцию sprintf или str_pad. Вот правильное решение:
<?php
$seconds = 3665;
// Целочисленное деление на 3600 — получаем часы
$hours = intdiv($seconds, 3600);
// Остаток от деления на 3600 — это секунды, оставшиеся после вычитания часов
$remaining = $seconds % 3600;
// Из остатка получаем минуты (целочисленное деление на 60)
$minutes = intdiv($remaining, 60);
// Оставшиеся секунды — это остаток от деления на 60
$secs = $remaining % 60;
// Форматируем с ведущими нулями
echo sprintf("%02d:%02d:%02d", $hours, $minutes, $secs);
// Результат: 01:01:05
?>
Объяснение по шагам
- intdiv — функция для целочисленного деления. В отличие от обычного
/, она сразу возвращает целое число (int), отбрасывая дробную часть. Альтернатива:(int)($seconds / 3600)илиfloor($seconds / 3600). - Оператор % — остаток от деления. Он даёт нам то, что не делится нацело. Например, 3665 % 3600 = 65 (это секунды, оставшиеся после вычитания одного часа).
- sprintf("%02d", ...) — форматирует число так, чтобы оно занимало минимум 2 символа, а если цифр меньше — добавляет спереди ноль. То есть 1 превращается в "01", 5 — в "05".
Альтернативный вариант с str_pad
Если по каким-то причинам не хотите использовать sprintf, можно сделать так:
<?php
$hours = intdiv($seconds, 3600);
$minutes = intdiv($seconds % 3600, 60);
$secs = $seconds % 60;
echo str_pad($hours, 2, '0', STR_PAD_LEFT) . ':' .
str_pad($minutes, 2, '0', STR_PAD_LEFT) . ':' .
str_pad($secs, 2, '0', STR_PAD_LEFT);
// Результат: 01:01:05
?>
Что делать, если секунд меньше часа?
Код корректно обработает и такие случаи. Например, для 65 секунд:
<?php
$seconds = 65;
$hours = intdiv($seconds, 3600); // 0
$minutes = intdiv($seconds % 3600, 60); // 1
$secs = $seconds % 60; // 5
echo sprintf("%02d:%02d:%02d", $hours, $minutes, $secs); // 00:01:05
?>
Готовое решение в виде функции
Для многократного использования рекомендую обернуть логику в функцию:
<?php
function secondsToHms(int $seconds): string {
$hours = intdiv($seconds, 3600);
$minutes = intdiv($seconds % 3600, 60);
$secs = $seconds % 60;
return sprintf("%02d:%02d:%02d", $hours, $minutes, $secs);
}
echo secondsToHms(3665); // 01:01:05
echo secondsToHms(75); // 00:01:15
?>
Этот подход работает для любых неотрицательных целых чисел. Если нужно поддерживать отрицательные значения (например, для таймера обратного отсчёта), добавьте проверку на abs().
Использование встроенной функции gmdate
Если не хотите писать собственную логику деления, PHP предоставляет удобную функцию gmdate, которая форматирует метку времени Unix. Однако есть нюанс: она работает только для интервалов меньше 24 часов (86400 секунд), так как даты начинаются с 00:00:00. Для больших значений часы будут обнуляться.
<?php
$seconds = 3665;
echo gmdate("H:i:s", $seconds); // 01:01:05
// Но для 90000 секунд (25 часов) выведет 01:00:00, а не 25:00:00
?>
Когда это удобно
Этот метод идеален, если ваше время гарантированно меньше 24 часов — например, для длительности видео, аудиозаписей или коротких таймеров. Код получается очень компактным и читаемым.
Решение для любого количества часов (включая >24)
Если нужно поддерживать произвольные значения, комбинируйте gmdate с ручным вычислением часов:
<?php
$seconds = 90000; // 25 часов
$hours = floor($seconds / 3600);
$remaining = $seconds % 3600;
echo sprintf("%02d:%s", $hours, gmdate("i:s", $remaining));
// Результат: 25:00:00
?>
Этот подход берёт часы через деление, а минуты и секунды — через gmdate, что избавляет от ручного вычисления остатков. Но для простых случаев (секунды < 86400) достаточно одного вызова gmdate.