Разбор даты в Python: fromisoformat, strptime и часовой пояс

Разбор даты в Python: fromisoformat, strptime и часовой пояс
Содержание статьи

Выбирайте парсер по договорённости о входных данных. Для поддерживаемой ISO-строки подойдёт datetime.fromisoformat(), для известного собственного формата используйте datetime.strptime(). Отдельно проверьте часовой пояс: успешно прочитанная дата ещё не обязательно обозначает однозначный момент времени.

ISO-строка со смещением

Пример рассчитан на Python 3.11 и новее. Строка содержит дату, время и смещение +03:00, поэтому результат знает своё отличие от UTC.

from datetime import datetime, timezone

local = datetime.fromisoformat("2026-10-31T09:15:00+03:00")
utc = local.astimezone(timezone.utc)
print(utc.isoformat())  # 2026-10-31T06:15:00+00:00

astimezone() сохраняет момент и меняет его представление. Вызов replace(tzinfo=timezone.utc) здесь был бы ошибкой: он оставил бы часы 09:15 и приписал им UTC. Это другой момент. В современных версиях Python fromisoformat() также принимает окончание Z для UTC, но не является универсальным парсером любой записи даты.

Известный формат через strptime

Если источник отдаёт день, месяц и год через точки, задайте шаблон явно. Директивы %d, %m, %Y, %H и %M обозначают день, месяц, полный год, часы и минуты.

parsed = datetime.strptime("31.10.2026 09:15", "%d.%m.%Y %H:%M")
print(parsed.isoformat())  # 2026-10-31T09:15:00
print(parsed.tzinfo)       # None

try:
    datetime.strptime("31.02.2026", "%d.%m.%Y")
except ValueError:
    print("Некорректная дата")

Второй результат не содержит часового пояса. Такой datetime называют naive; объект с достаточной информацией о смещении называют aware. Нельзя молча считать naive-время московским или UTC: это должно следовать из контракта источника. Для именованной зоны с сезонными переходами отдельно нужен разбор её правил, а не постоянное числовое смещение.

Не угадывайте неоднозначную дату

Запись 03/04/2026 может означать 3 апреля или 4 марта. Последовательный перебор двух шаблонов не устраняет неоднозначность: оба варианта могут оказаться допустимыми. Лучше требовать согласованный формат или отклонять такую запись с понятной ошибкой.

Обрабатывайте ValueError рядом с границей ввода и сохраняйте контекст ошибки в своей диагностике. Подставлять текущую дату вместо неверной опасно: запись выглядит исправной, хотя исходные данные не удалось прочитать. Сравнение aware и naive значений по порядку также требует предварительного согласования их смысла.

Минимальный набор проверок

  • Обычная дата и допустимый високосный день.
  • Несуществующий день месяца и несовпадающий формат.
  • Одинаковый момент с разными смещениями после перевода в UTC.
  • Отсутствующий часовой пояс: явный отказ либо документированное правило источника.

Подобные преобразования удобно отрабатывать в задачах импорта на курсах Python. На Mentoring.digital можно найти и наставника для разбора Python-кода, чтобы проверить контракт входных данных до подключения реального источника.

Похожие статьи по данной теме