Python datetime: методы для работы с датами и временем
Основные возможности модуля datetime
Модуль datetime в Python предоставляет классы для манипуляции датами и временем. Основные классы: datetime (дата+время), date (только дата), time (только время), timedelta (интервал), timezone (часовой пояс).
Как получить текущую дату и время, отформатировать и выполнить базовые операции?
Базовое решение - использовать datetime.now() и timedelta. Пример:
from datetime import datetime, timedelta, date, time
now = datetime.now()
print(now)
# форматирование в строку
formatted = now.strftime("%Y-%m-%d %H:%M:%S")
print(formatted)
# разбор строки
dt = datetime.strptime("2023-12-31 23:59", "%Y-%m-%d %H:%M")
print(dt)
# добавление 7 дней
future = now + timedelta(days=7)
print(future)время создания python (время создания файла/объекта в python)
Пояснение: datetime.now() возвращает текущее локальное время (наивный datetime без часового пояса). strftime преобразует datetime в строку; strptime делает обратную операцию. timedelta позволяет выполнять арифметику с датами.
Типичные ошибки и проблемы:
- Использование наивного datetime без часового пояса при сравнении с UTC может дать неверный результат. Рекомендуется применять aware datetime через
timezone.utcилиZoneInfo. - Неверный формат в
strptimeвызываетValueError. Следует сверять строку с шаблоном. - При сложении
timedelta(months=1)нет - месяцы имеют разную длину, для этого нужна сторонняя библиотекаdateutil.
Как работать с datetime в разных часовых поясах?
Использование модуля zoneinfo (Python 3.9+) или pytz. Пример с zoneinfo:
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
utc_now = datetime.now(timezone.utc)
msk = utc_now.astimezone(ZoneInfo("Europe/Moscow"))
print(msk)
# перевод из одной зоны в другую
ny = datetime.now(ZoneInfo("America/New_York"))
print(ny)время сообщения python (время сообщения (метка времени) в python)
Цель: корректное отображение времени в разных регионах, учёт летнего/зимнего времени. Случаи использования: веб-приложения, логи, международные системы.
Проблемы:
- При использовании
pytzнеобходимо вызывать методlocalize()для наивного datetime, иначе оффсет может быть неверным. - База данных часовых поясов обновляется - для свежих данных нужно обновлять пакет.
Как преобразовать datetime в Unix timestamp и обратно?
Методы timestamp() и fromtimestamp():
from datetime import datetime, timezone
dt = datetime(2025, 1, 1, tzinfo=timezone.utc)
ts = dt.timestamp()
print(ts) # 1735689600.0
dt2 = datetime.fromtimestamp(ts, tz=timezone.utc)
print(dt2)дата и время в python (работа с датой и временем в python)
Пояснение: timestamp() возвращает количество секунд с 1 января 1970 UTC. Для наивного datetime он интерпретируется как локальное время, что может привести к ошибке. Поэтому всегда указывайте tzinfo.
Ошибка:
Если не указать часовой пояс при обратном преобразовании, fromtimestamp вернёт локальное время, а не UTC. Это может быть незаметно при тестировании в одном часовом поясе.
Как вычислять разницу между датами и добавлять интервалы?
Использование timedelta:
from datetime import datetime, timedelta
d1 = datetime(2024, 1, 15)
d2 = datetime(2024, 2, 20)
diff = d2 - d1
print(diff.days) # 36
new_date = d1 + timedelta(weeks=3)
print(new_date)модуль время python (модуль time в python)
Применение: расчёт продолжительности событий, добавление/вычитание дней, секунд. Ограничение: timedelta не поддерживает месяцы и годы из-за непостоянной длины. Для этого подходит dateutil.relativedelta.
Как преобразовать дату в строку и обратно (форматирование и парсинг)?
Методы strftime и strptime:
from datetime import datetime
dt = datetime(2024, 6, 15, 14, 30, 45)
print(dt.strftime("%A, %d %B %Y %I:%M %p")) # Saturday, 15 June 2024 02:30 PM
# парсинг с нестандартным разделителем
s = "2024/06/15-14:30:45"
parsed = datetime.strptime(s, "%Y/%m/%d-%H:%M:%S")
print(parsed)Python определить время (определение времени в python)
Случаи: логи, файлы, пользовательский ввод. Проблемы: названия месяцев и дней недели зависят от локали. Для русского языка нужно сначала установить локаль через locale.setlocale().
Ошибка:
Неправильный код формата (например, %y вместо %Y) приведёт к неверному году. Всегда проверяйте таблицу кодов.
Как получить количество дней в месяце, день недели, високосный год?
Модуль calendar и метод date.weekday():
import calendar
from datetime import date
print(calendar.isleap(2024)) # True
print(calendar.monthrange(2024, 2)) # (3, 29) - первый день недели (0=пн) и число дней
d = date(2024, 7, 4)
print(d.weekday()) # 3 (четверг)
print(d.isoweekday())# 4 (ISO: 1=пн)Python время года (определение времени года по дате в python)
Использование: проверка корректности дат, построение календарей. Путаница: weekday() возвращает 0 для понедельника, isoweekday() 1 для понедельника.
Как работать только с датами без времени?
Класс date:
from datetime import date, timedelta
today = date.today()
print(today)
future = today + timedelta(days=10)
print(future)
if future > today:
print("future is later")Python реальное время (получение реального времени в python)
Когда использовать: даты рождения, события без привязки ко времени. Операции аналогичны datetime, но без компонента времени.
Как работать только с временем без даты?
Класс time:
from datetime import time
t = time(14, 30, 45, 123456)
print(t.hour, t.minute, t.second, t.microsecond)
t1 = time(10, 0)
t2 = time(12, 0)
print(t1 < t2) # True
Особенности: time не поддерживает арифметику (нельзя прибавить timedelta). Для операций со временем нужно комбинировать с date или использовать datetime.
Расширенные примеры работы с datetime
Пример 1: Вычисление возраста по дате рождения
Корректный расчёт с учётом месяца и дня:
from datetime import date
birth = date(1990, 5, 17)
today = date.today()
age = today.year - birth.year - ((today.month, today.day) < (birth.month, birth.day))
print(age)
35
Пояснение: Вычитание года, затем проверка, был ли уже день рождения в этом году. Если нет - уменьшаем возраст на 1.
Пример 2: Генерация списка дат на месяц
from datetime import date, timedelta
start = date(2024, 1, 1)
dates = [start + timedelta(days=i) for i in range(31)]
print(dates[:5])
[datetime.date(2024, 1, 1), datetime.date(2024, 1, 2), datetime.date(2024, 1, 3), datetime.date(2024, 1, 4), datetime.date(2024, 1, 5)]
Применение: для отчётов, календарей, расчёта периодов.
Пример 3: Парсинг ISO 8601 с часовым поясом (Python 3.11+)
from datetime import datetime
s = "2024-12-25T10:30:00+03:00"
dt = datetime.fromisoformat(s)
print(dt)
print(dt.tzinfo)
2024-12-25 10:30:00+03:00 datetime.timezone(datetime.timedelta(seconds=10800))
Замечание: fromisoformat в Python 3.7 поддерживал только формат YYYY-MM-DDTHH:MM:SS, начиная с 3.11 - расширенная поддержка. Для старых версий можно использовать dateutil.parser.
Пример 4: Поиск ближайшего рабочего дня (пн-пт)
from datetime import date, timedelta
def next_workday(d):
while d.weekday() >= 5: # 5=суббота, 6=воскресенье
d += timedelta(days=1)
return d
d = date(2024, 12, 28) # суббота
print(next_workday(d)) # 2024-12-30 (понедельник)
2024-12-30
Пример 5: Добавление месяцев с помощью dateutil.relativedelta
Требуется установка пакета python-dateutil. Позволяет корректно обрабатывать последний день месяца:
from datetime import date
from dateutil.relativedelta import relativedelta
d = date(2024, 1, 31)
new_d = d + relativedelta(months=1)
print(new_d) # 2024-02-29 (високосный год)
2024-02-29
Объяснение: relativedelta учитывает разную длину месяцев, при превышении последнего дня месяца берётся последний день следующего.
Пример 6: Использование микросекунд при работе с временными метками
from datetime import datetime, timezone
ts = 1704067200.123456 # 2024-01-01 00:00:00.123456 UTC
dt = datetime.fromtimestamp(ts, tz=timezone.utc)
print(dt.microsecond) # 123456
print(dt)
123456 2024-01-01 00:00:00.123456+00:00
Обратное преобразование: dt.timestamp() вернёт дробную часть.