Руководство по использованию модуля time в Python

Введение
Модуль time — это базовый инструмент для работы со временем в Python. Он не требует установки: достаточно импортировать его в скрипте:
import timeМы пройдёмся по наиболее часто используемым функциям: epoch и текущая метка, gmtime/localtime, time(), ctime(), strftime(), sleep(), а также покажем альтернативы и практические приёмы для серверного и клиентского кода.
Краткая терминология
- Epoch — «начало отсчёта» для меток времени. В Unix-подобных системах это 1970-01-01T00:00:00 UTC.
- time.struct_time — кортежоподобная структура с полями года, месяца, дня, часа и т.д.
- UTC/GMT — координированное/среднее гринвичское время (не учитывает локальный сдвиг).
Получение базового epoch
На большинстве систем epoch начинается с 1970-01-01 00:00:00 UTC. Посмотреть базовую структуру можно так:
import time
default_base = time.gmtime(0)
print(default_base)
time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1,
tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3,
tm_yday=1, tm_isdst=0)
gmtime(0) возвращает структуру времени, соответствующую нулевой отметке epoch в UTC. Для локального представления используйте time.localtime(0):
import time
default_base = time.localtime(0)
print(default_base)Значения могут отличаться в зависимости от ОС и настроек часового пояса (например, при летнем времени tm_hour может быть отличным от 0).
Текущее время и детали
Получить текущее время в виде time.struct_time:
import time
current_time = time.gmtime()
print(current_time)
time.struct_time(tm_year=2021, tm_mon=10, tm_mday=2,
tm_hour=11, tm_min=13, tm_sec=18, tm_wday=5,
tm_yday=275, tm_isdst=0)Для локального времени замените gmtime() на localtime().
Число секунд с epoch
Функция time.time() возвращает количество секунд с epoch в виде float:
import time
print("Time difference in seconds:", time.time())
Time difference in seconds: 1633178361.142249Пример вычисления приближённого количества лет от epoch:
import time
# Calculate the number of years:
print("Year difference is approximately:", round(time.time() / (3600 * 365 * 24)), "years")
Year difference is approximately: 52 yearsВажно: подобные приближённые расчёты игнорируют високосные годы и корректировки, поэтому годовые оценки дают только грубое представление.
Доступ к полям времени и форматирование
Вы можете получить отдельные поля из структуры времени:
import time
current_local_time = time.localtime()
hours = current_local_time.tm_hour
mins = current_local_time.tm_min
year = current_local_time.tm_year
print(("The local time and year detail are: {}th hour, {}mins, and year {}").format(hours, mins, year))
The local time and year detail are: 11th hour, 49mins, and year 2021Для простого строкового вывода текущего локального времени используйте time.ctime():
import time
print(time.ctime())
Sat Oct 2 13:58:07 2021Чтобы контролировать формат вывода, применяйте time.strftime() и форматные спецификаторы:
import time
current_local_time = time.localtime()
# Stringify the current local time using string annotations:
dtime = time.strftime("The date and time is: %a, %d-%b-%Y, %I:%M %p", current_local_time)
print(dtime)
The date and time is: Sat, 02-Oct-2021, 11:57 AMКороткие подсказки по спецификаторам: %a — сокращённое имя дня, %d — число месяца, %b — сокращённое имя месяца, %Y — год 4 цифры, %I — час в 12‑часовом формате, %H — час в 24‑часовом формате, %p — AM/PM.
Паузы и планирование: time.sleep()
time.sleep(secs) приостанавливает выполнение текущего потока на secs секунд (принимаются int или float):
import time
time.sleep(3)
print("This post will show after 3 seconds")Для задержки на час используйте 3600 секунд:
time.sleep(3600)
print("This post will show after an hour")Применения: ограничение скорости (rate limiting), задержки в опросе внешних API, простая синхронизация потоков. Для продвинутых планировщиков лучше использовать asyncio/cron/jobbable libraries.
Пример: таймер обратного отсчёта
Оригинальный пример с вводом числа секунд и обратным отсчётом:
import time
print("Start counting seconds from:")
# Create a timer input field that accepts an integer
timer = int(input())
# Increment the timer so that it starts at the specified input
timer = range(timer + 1)
# Assign the length of the timer to a new variable =>
# Then remove one from timer's length to match its index
v = len(timer) - 1
for i in timer:
# Increment the time every one second
time.sleep(1)
# Concatenate the previous count with the next count
# to prevent new line at each iteration
print(timer[v], end = " ", flush=True)
print("\r", end = "", flush=True)
# Decrease the length of timer input by one for each iteration
v -= 1Этот код делает обратный отсчёт; при необходимости можно улучшить обработку ошибок ввода и вывод в более удобном формате.
Практические рекомендации и когда применять другие библиотеки
- Для простых временных меток, пауз и форматирования подойдёт time.
- Для задач с часовыми поясами, локализацией формата даты/времени и корректной работы с DST используйте datetime + zoneinfo (Python 3.9+) или dateutil/pytz на старых версиях.
- Для измерения коротких промежутков и высокоточной временной метрики используйте time.perf_counter() или time.process_time() для CPU‑времени. time.time() может отдавать системное время, которое подвержено коррекции системного часовщика.
- Для монотонного измерения интервалов времени используйте time.monotonic(). Она не уходит назад при изменении системных часов.
Пример использования perf_counter для точного измерения исполнения:
import time
start = time.perf_counter()
# код, который нужно измерить
end = time.perf_counter()
print(f"Элпсед: {end - start} секунд")Частые ошибки и подводные камни
- Использование time.time() для измерения длительности, когда системный час может быть подкорректирован (NTP) — лучше использовать monotonic/perf_counter.
- Попытка оперировать часовыми поясами только через offset tm_gmtoff/ tm_zone (C-структуры) — лучше стандартные средства zoneinfo/dateutil.
- Предположение, что epoch везде одинаков — на некоторых системах (старые или встраиваемые) epoch может отличаться.
- Использование time.sleep() для точного тайминга в реальном времени — sleep не гарантирует точного пробуждения и зависит от планировщика ОС.
Чек‑лист для бекенд‑разработчика
- Логирование: сохраняйте метки времени в UTC (time.time() или datetime.utcnow().isoformat()).
- Измерение производительности: используйте perf_counter/monotonic.
- Планирование заданий: для повторяющихся задач применяйте планировщик (cron, Celery, APScheduler), а не только sleep.
- Проверка совместимости: протестируйте поведение на целевых ОС (Linux, Windows, macOS).
- Формат вывода: если нужен человекочитаемый локализованный формат — используйте datetime + locale/zoneinfo.
Шпаргалка (cheat sheet)
- time.time() — секундная метка с плавающей точкой от epoch (системное время).
- time.gmtime([secs]) — UTC struct_time.
- time.localtime([secs]) — локальный struct_time.
- time.ctime([secs]) — человекочитаемая строка локального времени.
- time.strftime(format, t) — форматирование struct_time.
- time.sleep(secs) — пауза.
- time.perf_counter() — высокоточное монотонное время для измерений.
- time.monotonic() — монотонная временная метрика.
- time.process_time() — CPU‑время текущего процесса.
Мини‑методология для добавления таймингов в проект
- Решите, для чего нужны метки: логирование, измерение, синхронизация, UI.
- Для логов используйте UTC и ISO‑формат.
- Для измерений — perf_counter/monotonic.
- Для локализованного отображения — datetime + zoneinfo.
- Напишите модуль-обёртку, чтобы в проекте можно было легко заменить реализацию (например, переключиться на mock‑время для тестов).
Примеры тестов и критерии приёмки
- Тест: измерение выполнения функции должно возвращать положительное число, меньше заданного порога. Критерии приёмки: возвращаемое время < ожидаемого порога.
- Тест: функция форматирования должна возвращать строку, соответствующую регулярному выражению для ISO 8601. Критерии приёмки: совпадение с паттерном.
- Тест: при переводе системного времени вперёд/назад monotonic/perf_counter остаются монотонными. Критерии приёмки: второй вызов >= первого.
Безопасность и приватность
- Метки времени в логах могут содержать информацию о поведении пользователей. Храните логи согласно политике приватности и регуляторным требованиям.
- При экспортe логов для аналитики, при необходимости, обрабатывайте/анонимизируйте метки так, чтобы нельзя было однозначно привязать события к конкретному пользователю.
Сравнение: time vs datetime vs zoneinfo/dateutil
- time: лёгкий, быстрый, удобен для низкоуровневых операций и сна.
- datetime: богатая модель даты/времени, удобен для арифметики, форматирования и сериализации.
- zoneinfo/dateutil: необходимы, если нужно корректно работать с часовыми поясами и DST.
Модель принятия решений (Mermaid)
flowchart TD
A[Нужна временная метка?] --> B{Для логов или для измерений?}
B -->|Логи| C[Использовать UTC + time.time'' или datetime.utcnow'']
B -->|Измерения| D[Использовать perf_counter'' или monotonic'']
A --> E{Нужны часовые пояса?}
E -->|Да| F[Использовать datetime + zoneinfo или dateutil]
E -->|Нет| G[time / datetime достаточно]Полезные сценарии и альтернативы
- Планирование периодических задач: APScheduler, Celery Beat или system cron вместо бесконечных циклов с sleep.
- Часовые пояса и локализация: zoneinfo (стандарт), dateutil.tz для более старых версий Python.
- Высокоточные таймеры в реальном времени: специализированный таймер на уровне ОС или аппаратный таймер.
1‑строчный глоссарий
- Epoch — точка отсчёта времени; в Unix: 1970-01-01T00:00:00 UTC.
- Monotonic — метрика времени, которая не «идёт назад» при смене системных часов.
- Perf_counter — высокоточный источник времени для измерений.
Краткое резюме
Важно выбирать инструмент, исходя из цели: time удобен для простых задач, но для локализации и работы с часовыми поясами предпочтительнее datetime + zoneinfo/dateutil. Для точных измерений используйте perf_counter или monotonic, а для производства — централизованное логирование в UTC.
Примечание: при переносе кода между ОС протестируйте поведение функций времени, особенно если проект работает с таймштампами и расписаниями.
Вопросы и ответы
Q: Можно ли использовать time.time() для измерения длительности работы функции?
A: Лучше использовать time.perf_counter() или time.monotonic(), чтобы избежать влияния системных корректировок времени.
Q: Как правильно хранить метки времени в логах?
A: Храните в UTC в ISO 8601 формате; это упрощает агрегацию и анализ.
Похожие материалы
Как массово закрыть приложения на Mac
Xbox One не подключается к Wi‑Fi — как исправить
Как скачать старые версии Internet Explorer
PayPal для побочного заработка — приёмы и чеклисты
Конвертация M4A в MP3 на iPhone без компьютера