В Python для работы с датой и временем используют модуль datetime. Он покрывает основные сценарии: хранение, вычисления, форматирование и учёт часовых поясов. Ниже — практические примеры без лишней теории.
Базовые типы: date, time, datetime
date— только дата (год, месяц, день).time— только время (часы, минуты, секунды).datetime— дата и время вместе.
Примеры создания:
from datetime import date, time, datetime d = date(2025, 7, 15) t = time(14, 30, 5) dt = datetime(2025, 7, 15, 14, 30, 5) print(d) # 2025-07-15 print(t) # 14:30:05 print(dt) # 2025-07-15 14:30:05

Часто используют datetime.now() для текущей даты и времени:
now = datetime.now() print(now)
Получение отдельных частей даты
У объектов есть атрибуты, по которым удобно брать отдельные значения:
dt = datetime(2025, 7, 15, 14, 30, 5) print(dt.year) # 2025 print(dt.month) # 7 print(dt.day) # 15 print(dt.hour) # 14 print(dt.minute) # 30 print(dt.second) # 5
Это полезно, когда нужно отдельно проверить год, месяц и т. п.
Форматирование: strftime и разбор строки: strptime
Форматирование в строку (strftime)
Превращаем datetime в строку по шаблону:
dt = datetime(2025, 7, 15, 14, 30, 5) s = dt.strftime("%Y-%m-%d %H:%M:%S") print(s) # 2025-07-15 14:30:05
Частые коды формата:
%Y— год (4 цифры),%y— год (2 цифры)%m— месяц (01–12),%d— день (01–31)%H— час (00–23),%M— минуты,%S— секунды%B— полное название месяца,%b— сокращённое%A— полное название дня недели,%a— сокращённое
Пример с разными форматами:
dt = datetime.now() print(dt.strftime("%d.%m.%Y")) # 15.07.2025 print(dt.strftime("%B %d, %Y")) # July 15, 2025 print(dt.strftime("%A, %d %B %Y, %H:%M")) # Tuesday, 15 July 2025, 14:30
Разбор строки в datetime (strptime)
Когда дата приходит как текст (из файла, API, формы), её нужно превратить в объект:
s = "2025-07-15 14:30:05" dt = datetime.strptime(s, "%Y-%m-%d %H:%M:%S") print(dt, type(dt)) # datetime.datetime объект
Важно: шаблон должен точно соответствовать строке, иначе будет ValueError.
Вычисления с датами: timedelta
Для прибавления/вычитания дней, часов и т. д. используют timedelta:
from datetime import datetime, timedelta now = datetime.now() tomorrow = now + timedelta(days=1) week_ago = now - timedelta(weeks=1) three_hours_later = now + timedelta(hours=3) print("Сейчас:", now) print("Завтра:", tomorrow) print("Неделю назад:", week_ago) print("Через 3 часа:", three_hours_later)
timedelta поддерживает: days, seconds, microseconds, milliseconds, minutes, hours, weeks.

Пример: посчитать разницу между двумя датами:
start = datetime(2025, 7, 1, 10, 0) end = datetime(2025, 7, 3, 14, 30) diff = end - start print(diff) # 2 days, 4:30:00 print(diff.total_seconds())# общее число секунд print(diff.days) # только дни
Часовые пояса: naive и aware объекты
Есть два типа datetime:
- naive — без часового пояса (по умолчанию).
- aware — с часовым поясом (более правильный вариант для реальных систем).
Простой способ (Python 3.9+): zoneinfo
from datetime import datetime from zoneinfo import ZoneInfo # Москва dt_msk = datetime(2025, 7, 15, 12, 0, tzinfo=ZoneInfo("Europe/Moscow")) # Нью‑Йорк dt_ny = datetime(2025, 7, 15, 12, 0, tzinfo=ZoneInfo("America/New_York")) print(dt_msk) # 2025-07-15 12:00:00+03:00 print(dt_ny) # 2025-07-15 12:00:00-04:00
Конвертация между поясами:
dt_msk = datetime.now(ZoneInfo("Europe/Moscow")) dt_ny = dt_msk.astimezone(ZoneInfo("America/New_York")) print(dt_msk, "->", dt_ny)
Получение текущего времени в нужном поясе
from datetime import datetime from zoneinfo import ZoneInfo now_utc = datetime.now(ZoneInfo("UTC")) now_msk = datetime.now(ZoneInfo("Europe/Moscow")) print(now_utc) print(now_msk)
Практический пример: лог с временной меткой и конвертацией
Допустим, нужно сохранять события в UTC, а показывать пользователю в его поясе.
from datetime import datetime from zoneinfo import ZoneInfo def записать_событие(сообщение, часовой_пояс_пользователя="Europe/Moscow"): # Храним в UTC dt_utc = datetime.now(ZoneInfo("UTC")) # Конвертируем для отображения tz_user = ZoneInfo(часовой_пояс_пользователя) dt_local = dt_utc.astimezone(tz_user) timestamp_str = dt_utc.strftime("%Y-%m-%dT%H:%M:%SZ") display_str = dt_local.strftime("%d.%m.%Y %H:%M") return { "сообщение": сообщение, "timestamp_utc": timestamp_str, "время_для_пользователя": display_str, } event = записать_событие("Пользователь вошёл в систему") print(event)

Такой подход позволяет хранить единое время (UTC) и корректно показывать его в любом часовом поясе.
Ещё один пример: валидация и нормализация даты из строки
Пользователь присылает дату в формате DD.MM.YYYY. Нужно превратить в datetime, проверить диапазон и вернуть в нужном формате:
from datetime import datetime def нормализовать_дату(строка, формат_входа="%d.%m.%Y", формат_выхода="%Y-%m-%d"): try: dt = datetime.strptime(строка, формат_входа) # Пример проверки диапазона: не раньше 2000 года if dt.year < 2000: return None, "Год слишком ранний" return dt.strftime(формат_выхода), None except ValueError: return None, "Неверный формат даты" res, err = нормализовать_дату("15.07.2025") if err: print("Ошибка:", err) else: print("Нормализованная дата:", res)
![]()
Частые ошибки и как их избежать
- Смешивание naive и aware объектов. Нельзя напрямую сравнивать или вычитать
datetimeс часовым поясом и без него — будетTypeError. Всегда приводите к одному типу (лучше к aware). - Неверный шаблон в
strptime. Если строка15/07/2025, а шаблон%Y-%m-%d, будет ошибка. Проверяйте соответствие. - Хранение локальных дат вместо UTC. Для систем, где есть пользователи из разных часовых поясов, храните время в UTC, конвертируйте только на уровне отображения.
- Использование
datetime.utcnow(). Этот метод устарел. Лучшеdatetime.now(ZoneInfo("UTC")).
- Для простых задач хватит
datetime.now(),strftime/strptime,timedelta. - Для корректной работы с разными регионами используйте aware‑объекты: в новых версиях —
zoneinfo, в старых —pytz. - Храните время в UTC, отображайте в локальном поясе пользователя.
- Всегда проверяйте формат при разборе строк и избегайте смешивания naive и aware дат.
