Python даты: форматы, преобразования и типичные ошибки
Основные подходы к форматированию дат в Python
Работа с датами и временем возникает при обработке логов, анализе данных, веб-разработке. Python предлагает несколько инструментов для преобразования дат в строки и обратно. Выбор зависит от формата входных данных, необходимости учёта часового пояса и сложности операций.
Модуль datetime: strftime и strptime
Наиболее универсальное решение для стандартных форматов предоставляет встроенный модуль datetime. Метод strftime(format) преобразует объект datetime в строку, а strptime(date_string, format) выполняет обратную операцию. Поддерживаются коды форматирования: %Y – год, %m – месяц, %d – день, %H – часы, %M – минуты, %S – секунды и другие.
from datetime import datetime
now = datetime.now()
formatted = now.strftime("%Y-%m-%d %H:%M:%S")
print(formatted)
Python формат даты (формат даты и времени в python)
2025-03-20 14:30:00
date_str = "2025-03-20 14:30:00"
parsed = datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")
print(parsed)
2025-03-20 14:30:00
Цель – быстрое форматирование и разбор при известном точном формате. Подходит для логов, файлов конфигурации, стандартных интерфейсов.
Частая ошибка – несовпадение строки и шаблона. Если в строке "2025-03-20" указать формат "%Y/%m/%d", возникнет ValueError. Решение – проверять данные или использовать try-except.
Варианты решения разных задач
Как преобразовать Unix timestamp в читаемую строку?
Модуль time позволяет работать с метками времени. Функция time.localtime(timestamp) преобразует timestamp в struct_time, а time.strftime форматирует его.
import time
ts = 1710922200
local_t = time.localtime(ts)
formatted = time.strftime("%Y-%m-%d %H:%M:%S", local_t)
print(formatted)
2025-03-20 14:30:00
Этот способ удобен при работе с API, возвращающими timestamp. Случай использования – логирование событий с метками времени.
Ошибка – путаница между локальным временем и UTC. Для UTC следует использовать time.gmtime.
Как выполнить арифметику с датами (добавить дни, недели)?
Класс timedelta из модуля datetime позволяет добавлять дни, секунды, микросекунды, минуты, часы, недели.
from datetime import datetime, timedelta
today = datetime.now()
next_week = today + timedelta(weeks=1)
print(next_week.strftime("%Y-%m-%d"))
2025-03-27
Цель – расчёт сроков, интервалов. Случаи – подписки, задачи, отчёты.
timedelta не поддерживает добавление месяцев или лет. Для этого требуется сторонняя библиотека, например dateutil.relativedelta.
Как распарсить дату из строки, если формат неизвестен или переменный?
Библиотека python-dateutil (установка pip install python-dateutil) предоставляет функцию parser.parse, которая пытается угадать формат.
from dateutil import parser
date_str = "March 20, 2025 2:30pm"
parsed = parser.parse(date_str)
print(parsed)
2025-03-20 14:30:00
Применяется при импорте данных из внешних источников (CSV, веб-страницы) с нестандартными форматами.
Неоднозначные даты, например "03/04/2025", могут интерпретироваться как 3 апреля (американский стиль) или 4 марта (европейский). Рекомендуется задавать аргументы dayfirst=True или yearfirst=True.
Как работать с часовыми поясами?
Библиотека pytz (установка pip install pytz) предоставляет базу данных часовых поясов. Для преобразования времени из UTC в другой пояс используется astimezone.
from datetime import datetime
import pytz
moscow = pytz.timezone('Europe/Moscow')
utc_now = datetime.now(pytz.UTC)
moscow_now = utc_now.astimezone(moscow)
print(moscow_now.strftime("%Y-%m-%d %H:%M %Z"))
2025-03-20 17:30 MSK
Цель – международные приложения, корректное отображение времени пользователя.
Ошибка – попытка вызвать astimezone для наивного (без часового пояса) datetime. Сначала требуется локализация через pytz.timezone.localize(datetime).
Расширенные примеры работы с датами
Здесь представлены менее распространённые, но полезные приёмы форматирования и парсинга дат в Python.
1. Использование f-строк со спецификаторами формата
Начиная с Python 3.6, внутри f-строк можно напрямую применять коды форматирования datetime.
from datetime import datetime
now = datetime.now()
print(f"Сейчас: {now:%Y-%m-%d %H:%M:%S}")
print(f"Микросекунды: {now:%f}")
# Для отображения часового пояса объект должен быть timezone-aware
Сейчас: 2025-03-20 14:30:00 Микросекунды: 123456
Такой подход упрощает встраивание дат в текстовые сообщения, логи, отчёты.
2. Разбор ISO 8601 методом fromisoformat (Python 3.7+)
Стандарт ISO 8601 широко используется в API и обмене данными. datetime.fromisoformat парсит большинство его вариантов.
iso_str = "2025-03-20T14:30:00+03:00"
parsed = datetime.fromisoformat(iso_str)
print(parsed)
2025-03-20 14:30:00+03:00
Внимание: в Python 3.6 и старше этот метод отсутствует; для совместимости используется сторонний парсер.
3. Генерация последовательности дат с dateutil.rrule
Библиотека dateutil включает класс rrule для создания повторяющихся дат по правилам (ежедневно, еженедельно и т.д.).
from dateutil.rrule import rrule, DAILY
from datetime import datetime
start = datetime(2025, 3, 1)
end = datetime(2025, 3, 5)
dates = list(rrule(DAILY, dtstart=start, until=end))
for d in dates:
print(d.strftime("%d.%m.%Y"))
01.03.2025 02.03.2025 03.03.2025 04.03.2025 05.03.2025
Применяется при построении расписаний, календарей, анализе временных рядов.
4. Добавление месяцев с relativedelta
В отличие от timedelta, relativedelta корректно обрабатывает разную длину месяцев.
from dateutil.relativedelta import relativedelta
from datetime import datetime
today = datetime(2025, 1, 31)
next_month = today + relativedelta(months=1)
print(next_month) # автоматически 28 февраля
2025-02-28 00:00:00
Полезно для финансовых расчётов, планирования.
5. Проблема двухзначного года при парсинге
Код %y в strptime интерпретирует года 00-68 как 2000-2068, а 69-99 как 1969-1999. Это может вызывать неожиданные результаты.
from datetime import datetime
print(datetime.strptime("70-03-20", "%y-%m-%d")) # 1970, а не 2070
print(datetime.strptime("25-03-20", "%y-%m-%d")) # 2025
1970-03-20 00:00:00 2025-03-20 00:00:00
Рекомендуется всегда использовать %Y с четырёхзначным годом, чтобы избежать путаницы.
6. Преобразование datetime в UTC timestamp без потери точности
Функция calendar.timegm принимает struct_time в UTC и возвращает timestamp. Она безопаснее, чемtime.mktime, которая ожидает локальное время.
import calendar
from datetime import datetime
utc_time = datetime(2025, 3, 20, 14, 30, 0)
ts = calendar.timegm(utc_time.timetuple())
print(ts)
# Обратное преобразование:
back = datetime.utcfromtimestamp(ts)
print(back)
1710922200 2025-03-20 14:30:00
Этот метод полезен при работе с базами данных или API, которые используют Unix-время.