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-время.

Формат даты и времени в Python - comments

En
Python формат даты (python)