Эффективное управление временными данными в Python

Раздел: Время -> Time

Основные подходы к работе со временем

Наиболее эффективное и современное решение для работы со временем в Python модуль datetime. Он предоставляет классы для представления и манипулирования датами, временем и временными интервалами. Основное преимущество объектная модель, которая позволяет выполнять арифметические операции, форматирование и парсинг без сложных преобразований.

from datetime import datetime, timedelta, date
# получение текущего момента
t_now = datetime.now()
print('Текущие дата и время:', t_now)
# создание конкретного момента
dt_custom = datetime(2025, 3, 10, 15, 30, 0)
print('Созданная дата:', dt_custom)
# разница между датами
delta = timedelta(days=7, hours=2)
future = t_now + delta
print('Через неделю и 2 часа:', future)
# форматирование
formatted = t_now.strftime('%d.%m.%Y %H:%M:%S')
print('Отформатированная дата:', formatted)
# парсинг строки
parsed = datetime.strptime('10.03.2025 12:00', '%d.%m.%Y %H:%M')
print('Распарсена:', parsed)

Python program time (работа со временем в python)

Текущие дата и время: 2025-03-10 14:22:33.456789
Созданная дата: 2025-03-10 15:30:00
Через неделю и 2 часа: 2025-03-17 16:22:33.456789
Отформатированная дата: 10.03.2025 14:22:33
Распарсена: 2025-03-10 12:00:00

Типичные ошибки при работе с datetime:

Проблема: неверный формат при strptime приводит к ValueError. Решение: всегда проверять соответствие кодов форматирования строке. Использовать таблицу кодов (например, %d день, %m месяц, %Y год, %H часы).

Проблема: попытка сложения datetime с datetime (а не timedelta). Решение: использовать timedelta.

Проблема: игнорирование часового пояса. Решение: использовать timezone-aware объекты (через pytz или zoneinfo).

Как получить количество секунд от эпохи Unix?

Для этого используется модуль time. Функция time.time() возвращает число секунд с 1 января 1970 года в виде float.

import time
unix_seconds = time.time()
print('Unix timestamp:', unix_seconds)
Unix timestamp: 1741613553.789012

Проблема: разные платформы могут иметь разное разрешение. Решение: для высокоточных замеров использовать time.perf_counter().

Как приостановить выполнение программы на заданное время?

Функция time.sleep(seconds) задерживает поток на указанное количество секунд.

print('Старт')
time.sleep(2.5)
print('Прошло 2.5 секунды')
Старт
(пауза 2.5 сек)
Прошло 2.5 секунды

Проблема: sleep блокирует весь поток. В многопоточных приложениях это может замедлить другие задачи. Решение: использовать асинхронные подходы (asyncio.sleep()) или таймеры.

Как работать с календарными данными, например, получить количество дней в месяце?

Модуль calendar предоставляет функции для работы с календарями.

import calendar
year = 2025
month = 2
print('Февраль 2025:', calendar.monthrange(year, month))  # (день недели первого дня, кол-во дней)
print('Календарь на месяц:')
print(calendar.month(year, month))
Февраль 2025: (5, 28)
Календарь на месяц:
   February 2025
Mo Tu We Th Fr Sa Su
                1  2
 3  4  5  6  7  8  9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28

Проблема: calendar.monthrange возвращает кортеж, его легко перепутать с другими функциями. Решение: явно распаковывать или обращаться по индексу с комментариями.

Как обрабатывать часовые пояса и летнее время?

Для этого используется сторонний модуль pytz (или встроенный zoneinfo в Python 3.9+).

from datetime import datetime
import pytz
tz_msk = pytz.timezone('Europe/Moscow')
tz_ny = pytz.timezone('America/New_York')
now_utc = datetime.now(pytz.utc)
print('UTC:', now_utc)
now_msk = now_utc.astimezone(tz_msk)
print('Москва:', now_msk)
now_ny = now_utc.astimezone(tz_ny)
print('Нью-Йорк:', now_ny)
UTC: 2025-03-10 12:22:33.456789+00:00
Москва: 2025-03-10 15:22:33.456789+03:00
Нью-Йорк: 2025-03-10 08:22:33.456789-04:00

Проблема: pytz не поддерживает автоматическое обновление базы данных часовых поясов. Решение: обновлять пакет или использовать zoneinfo, который использует системную базу.

Проблема: локальные объекты без tzinfo считаются naive и не могут быть корректно преобразованы. Решение: всегда указывать timezone при создании или использовать localize() из pytz.

Как измерить время выполнения функции с высокой точностью?

Функция time.perf_counter() возвращает время с максимально возможной точностью для измерения интервалов.

start = time.perf_counter()
# имитация работы
time.sleep(0.123)
end = time.perf_counter()
print(f'Время выполнения: {end - start:.6f} сек')
Время выполнения: 0.123456 сек

Проблема: perf_counter не привязан к реальному времени (может быть перезапущен при засыпании системы). Решение: для мониторинга длительных процессов использовать time.monotonic().

Расширенные примеры работы со временем

Пример
# Пример 1: вычисление возраста на основе даты рождения
from datetime import date
def calculate_age(birth_date_str):
    birth = date.fromisoformat(birth_date_str)  # 'YYYY-MM-DD'
    today = date.today()
    age = today.year - birth.year
    # проверка, был ли день рождения в этом году
    if (today.month, today.day) < (birth.month, birth.day):
        age -= 1
    return age

print('Возраст (2000-03-10):', calculate_age('2000-03-10'))
print('Возраст (2000-12-31):', calculate_age('2000-12-31'))
Возраст (2000-03-10): 25
Возраст (2000-12-31): 24
Пример
# Пример 2: количество рабочих дней между датами
import datetime
from dateutil import rrule  # требуется установка: pip install python-dateutil
start = datetime.date(2025, 1, 1)
end = datetime.date(2025, 1, 31)
workdays = rrule.rrule(rrule.DAILY, byweekday=(rrule.MO, rrule.TU, rrule.WE, rrule.TH, rrule.FR),
                       dtstart=start, until=end)
print('Количество рабочих дней в январе 2025:', workdays.count())
Количество рабочих дней в январе 2025: 23
Пример
# Пример 3: парсинг строки с временем в разных форматах
from datetime import datetime
log_entry = '2025-03-10 14:30:00,123 ERROR some message'
try:
    # пробуем стандартный ISO формат
    dt = datetime.fromisoformat(log_entry.split(',')[0])
    print('Распарсено ISO:', dt)
except ValueError:
    # альтернативный формат
    dt = datetime.strptime(log_entry[:19], '%Y-%m-%d %H:%M:%S')
    print('Распарсено strptime:', dt)
Распарсено ISO: 2025-03-10 14:30:00
Пример
# Пример 4: работа с временными зонами через zoneinfo (Python 3.9+)
from zoneinfo import ZoneInfo
from datetime import datetime
tz_tokyo = ZoneInfo('Asia/Tokyo')
tz_london = ZoneInfo('Europe/London')
now_tokyo = datetime.now(tz_tokyo)
now_london = now_tokyo.astimezone(tz_london)
print('Токио:', now_tokyo.strftime('%Y-%m-%d %H:%M %Z'))
print('Лондон:', now_london.strftime('%Y-%m-%d %H:%M %Z'))
Токио: 2025-03-10 21:22 +0900
Лондон: 2025-03-10 12:22 +0000
Пример
# Пример 5: измерение времени выполнения с использованием декоратора
import time
from functools import wraps

def timer(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.perf_counter()
        result = func(*args, **kwargs)
        elapsed = time.perf_counter() - start
        print(f'Функция {func.__name__} выполнилась за {elapsed:.6f} сек')
        return result
    return wrapper

@timer
def long_running():
    time.sleep(0.5)
    return "готово"

long_running()
Функция long_running выполнилась за 0.500123 сек
'готово'
Пример
# Пример 6: создание календаря на год с подсветкой выходных
import calendar

year = 2025
cal = calendar.TextCalendar()
for month in range(1, 13):
    print(calendar.month_name[month], year)
    # получаем список недель: каждая неделя кортеж из 7 элементов (0 если не в месяце)
    month_days = cal.monthdayscalendar(year, month)
    for week in month_days:
        line = ''
        for day in week:
            if day == 0:
                line += '   '
            else:
                # выделяем выходные (суббота и воскресенье) звездочкой
                day_of_week = calendar.weekday(year, month, day)
                if day_of_week >= 5:
                    line += f'*{day:2} '
                else:
                    line += f' {day:2} '
        print(line)
    print()
January 2025
       1   2   3   4*  5*
 6   7   8   9  10  11* 12*
13  14  15  16  17  18* 19*
20  21  22  23  24  25* 26*
27  28  29  30  31
... (остальные месяцы)

Работа со временем в Python - comments

En
Python program time (python)