Перейти к основному содержимому

Даты и время в Python

Разработчику

См. также: Работа с типами · Анализ данных — pandas · Работа с файлами и API

Модуль datetime

Стандартный пакет datetime (не путать с именем типа) покрывает календарные даты, время суток, длительности и часовые пояса. Для логов, отчётов, API и аналитики это основной инструмент; в pandas временные ряды опираются на те же идеи — см. практикум по pandas.

Основные типы:

ТипНазначение
dateКалендарный день (год, месяц, день)
timeВремя суток без даты
datetimeДата + время
timedeltaРазница двух моментов (дни, секунды, микросекунды)
timezoneСмещение от UTC (фиксированное)

Создание и «сейчас»

from datetime import date, datetime, time, timedelta

today = date.today()
now = datetime.now() # локальное время ОС, наивное

d = date(2026, 5, 25)
dt = datetime(2026, 5, 25, 14, 30, 0)
t = time(9, 0, 0)

datetime.now() и date.today() зависят от часового пояса системы. Для серверного кода предпочтительнее явная зона или UTC.


Наивные и осознанные (aware) объекты

Наивный datetime не содержит информации о поясе — только «стенные часы». Осознанный привязан к tzinfo (часто через zoneinfo в Python 3.9+).

from datetime import datetime, timezone
from zoneinfo import ZoneInfo

utc = datetime.now(timezone.utc)
moscow = datetime.now(ZoneInfo("Europe/Moscow"))

# перевод осознанного момента
moscow_from_utc = utc.astimezone(ZoneInfo("Europe/Moscow"))

Правило для backend и БД:

  • хранить и передавать UTC (или Unix timestamp);
  • переводить в локаль пользователя на границе (UI, отчёт);
  • не сравнивать наивный и осознанный datetime — будет TypeError.
# Ошибка — смешение наивного и aware
# naive < aware # TypeError

timedelta — арифметика длительностей

from datetime import datetime, timedelta

start = datetime(2026, 1, 1, 12, 0)
end = start + timedelta(days=7, hours=3)
delta = end - start
print(delta.days, delta.seconds) # целые дни и остаток секунд

timedelta не привязан к календарю: «+1 месяц» делают через dateutil.relativedelta (сторонняя библиотека) или логику pandas.


Форматирование и разбор строк

from datetime import datetime

dt = datetime(2026, 5, 25, 9, 5, 0)
text = dt.strftime("%Y-%m-%d %H:%M:%S") # "2026-05-25 09:05:00"
parsed = datetime.strptime("25.05.2026", "%d.%m.%Y")
КодЗначение
%YГод четырьмя цифрами
%mМесяц 01–12
%dДень
%HЧас 00–23
%MМинуты
%SСекунды

Для ISO 8601 удобнее методы экземпляра:

iso = dt.isoformat()
back = datetime.fromisoformat("2026-05-25T09:05:00+03:00")

В JSON API даты обычно сериализуют в строку UTC (...Z) или Unix timestamp — см. примеры в главе про файлы и API.


Часовые пояса и переход на летнее время

Фиксированный timezone(timedelta(hours=3)) не учитывает DST (летнее время). Для реальных регионов используйте zoneinfo.ZoneInfo (база IANA в стандартной библиотеке с 3.9) или pytz в legacy-коде.

Типичная ошибка: «добавить 24 часа» вместо «следующий календарный день» в поясе с переводом стрелок — сдвиг на час. Для бизнес-дат (дедлайн «до конца 25 мая») часто достаточно типа date без времени.


Связь с pandas и БД

  • pandas: pd.to_datetime(), индекс DatetimeIndex, dt.tz_localize / dt.tz_convert.
  • SQL: типы TIMESTAMP WITH TIME ZONE / DATETIME — драйвер возвращает datetime или строку; см. базы данных в Python.
  • Django: USE_TZ = True, модели DateTimeField хранят UTC в БД.

Практические рекомендации

  1. В логах — UTC + ISO формат.
  2. В тестах — фиксированные datetime, не now(), чтобы тесты были воспроизводимы.
  3. Сравнение «событие раньше дедлайна» — приводить обе стороны к одной зоне или к UTC.
  4. Для только даты рождения / даты документа — тип date, без времени и пояса.

Связанные материалы


См. также

Другие статьи этого же раздела в боковом меню (как на странице «О разделе»).