Длительность в секундах раскладывается на часы, минуты и остаток секунд целочисленной арифметикой. Для числа меньше 3600 обычно нужен формат M:SS, а начиная с 3600 — H:MM:SS. Минуты до часа не дополняют нулём, зато части после двоеточия всегда занимают две цифры.
Для такой задачи не нужны datetime и часовые пояса: речь идёт о длительности, а не о моменте на календаре. Все примеры ниже проверены на CPython 3.14.5.
Как получить минуты и остаток секунд
Оператор // даёт целую часть от деления, % — остаток. Для 609 секунд это 10 полных минут и 9 секунд:
total_seconds = 609
minutes = total_seconds // 60
seconds = total_seconds % 60
print(minutes, seconds)
10 9
Встроенная функция divmod(a, b) возвращает оба результата одной операцией. Для целых чисел результат совпадает с парой (a // b, a % b):
print(divmod(609, 60))
(10, 9)
Оба варианта корректны. divmod короче и явно показывает, что частное и остаток относятся к одному делению.
Как отделить часы
Разложение выполняют в два шага. Сначала число секунд делят на 60, затем полученные полные минуты ещё раз делят на 60:
total_minutes, seconds = divmod(7322, 60)
hours, minutes = divmod(total_minutes, 60)
print(hours, minutes, seconds)
2 2 2
После второго divmod переменная minutes содержит только минуты внутри текущего часа, то есть число от 0 до 59. Переменная hours не ограничена числом 23: длительность может продолжаться больше суток.
hours, remainder = divmod(27 * 3600 + 5, 3600)
print(hours, remainder)
27 5
Обычные часы показали бы 03:00 следующего дня, но длительность должна сохранить все 27 часов.
Ведущие нули и граница формата
Спецификация 02d означает: вывести целое число в поле шириной не меньше двух знаков и заполнить свободное место нулём слева.
minutes = 10
seconds = 9
hours = 2
print(f"{minutes}:{seconds:02d}")
print(f"{hours}:{minutes:02d}:{seconds:02d}")
10:09
2:10:09
Ширина минимальная, а не максимальная. Значение 125 при формате 02d останется 125; Python не обрежет цифры. Поэтому часы можно выводить без отдельного ограничения.
Ноль нужен не всем частям. В формате без часов минуты выводят как обычное число: 1:05, а не 01:05. В формате с часами и минуты, и секунды стоят между разделителями, поэтому обе части двузначные.
Граница между двумя форматами
Ветвление зависит от общего числа секунд, а не от остатка после деления. Граница проходит ровно по 3600:
| Секунды | Разложение | Формат результата |
|---|---|---|
0 | 0 минут, 0 секунд | 0:00 |
59 | 0 минут, 59 секунд | 0:59 |
60 | 1 минута, 0 секунд | 1:00 |
3599 | 59 минут, 59 секунд | 59:59 |
3600 | 1 час, 0 минут, 0 секунд | 1:00:00 |
7322 | 2 часа, 2 минуты, 2 секунды | 2:02:02 |
Проверка hours > 0 даёт ту же границу для неотрицательных целых значений. Сравнение seconds > 3600 ошибочно: ровно 3600 секунд уже должны попасть в часовой формат.
Неверный вход и лишние инструменты
Оператор / возвращает число с плавающей точкой. Для форматирования отдельных единиц оно не нужно:
print(75 / 60)
print(divmod(75, 60))
1.25
(1, 15)
Округление 1.25 не вернёт одновременно и полные минуты, и остаток. Целочисленное деление сохраняет обе части без промежуточного float.
Что делать с отрицательным значением
Отрицательная длительность не имеет смысла в карточке видео. Если контракт запрещает её, проверку ставят до деления и останавливают выполнение через ValueError:
seconds = -1
try:
if seconds < 0:
raise ValueError("seconds must be non-negative")
except ValueError as error:
print(type(error).__name__, str(error))
ValueError seconds must be non-negative
Не заменяйте отрицательное число нулём молча. Такое исправление скрывает ошибку вызывающего кода и делает неверные данные похожими на валидные.
Тип входа тоже задаёт контракт. Если функция принимает только int, преобразование через int(value) способно незаметно отбросить дробную часть: int(1.9) даёт 1. В публичном API тип лучше проверить отдельно, а в учебной задаче достаточно следовать заявленному входу.
Почему timedelta выдаёт другую строку
datetime.timedelta умеет хранить длительности, но его стандартное строковое представление не совпадает с коротким форматом видеоплеера:
from datetime import timedelta
print(timedelta(seconds=75))
0:01:15
Для 75 секунд здесь появились часы и двузначные минуты. Подгонять эту строку срезами сложнее и хрупче, чем сразу собрать нужные части из целых чисел.
Частые ошибки
| Ошибка | Результат |
|---|---|
использовать / вместо // или divmod | появляются дробные минуты |
проверять seconds > 3600 | значение 3600 получает неверный формат |
писать {seconds} без :02d | получается 10:9 вместо 10:09 |
| дополнять минуты в коротком формате | получается 01:15 вместо 1:15 |
брать минуты как total_seconds // 60 после появления часов | выходит 1:61:01 вместо часового остатка |
| пропускать проверку отрицательного входа | отрицательная арифметика даёт формально корректную, но бессмысленную строку |
Если ошибка находится не в арифметике, а в скобках или двоеточии f-строки, сверьтесь с разбором SyntaxError в Python.
Как закрепить механику
В задаче «Форматирование длительности» нужно выбрать один из двух форматов, корректно обработать границу 3600 и вернуть строку. Соберите функцию из разобранных операций самостоятельно: проверки входа, двух делений с остатком и форматирования нужной ветки.
Базовые условия, функции и строки собраны в пути «Python для начинающих». После статьи полезно проверить минимум пять значений вокруг границ: 0, 59, 60, 3599 и 3600.