# Понимание времени в Python: полное руководство по datetime > **Серия 03 – операции с датой/временем, часовые пояса, преобразование форматов** Время – это не просто строка. Дни сменяются, месяцы переходят, летнее время вступает в силу, а в разных регионах правила различаются. Поэтому при работе с датой и временем важно различать «отображаемую строку» и «числовое значение», а также учитывать часовые пояса. ![Магический кабинет часового мастера](/media/editor_temp/6/5843a4cb-f3a6-4d8d-9a13-89c1cbb0ef6c.png) В этой статье мы сосредоточимся на модуле `datetime` и разберём: * Создание текущего времени и даты * Вычисление периодов (`timedelta`) * Форматирование и разбор строк (`strftime`, `strptime`) * Работа с часовыми поясами (`timezone`, `zoneinfo`) * Частые ошибки и надёжные шаблоны --- ## 1. Что предоставляет `datetime`? {#sec-5f3cbdfb3d40} В `datetime` есть несколько типов, которые выглядят похожими, но выполняют разные задачи. * `date` – только год‑месяц‑день * `time` – только часы‑минуты‑секунды * `datetime` – дата и время (самый распространённый тип) * `timedelta` – разница во времени (период) * `timezone` – фиксированный смещение часового пояса (например, UTC+9) Начиная с Python 3.9 в стандартную библиотеку вошёл модуль `zoneinfo`, упрощающий работу с региональными часовыми поясами (например, Asia/Tokyo). --- ## 2. Как получить «сейчас»: naive vs aware {#sec-80466bd4f739} ### 2.1 Что такое naive и aware? {#sec-893b0793d467} Объекты `datetime` делятся на две категории. * **naive datetime** – без информации о часовом поясе * **aware datetime** – с информацией о часовом поясе (`tzinfo`) Смешивание этих типов при вычислениях может привести к ошибкам или неожиданным результатам. ### 2.2 Рекомендуемое значение по умолчанию: начать с UTC aware {#sec-f876fdec8f2b} Единый стандарт UTC упрощает хранение и расчёты. ```python from datetime import datetime, timezone utc_now = datetime.now(timezone.utc) # aware (UTC) print(utc_now) ``` Если нужна локальная дата, преобразуем на этапе отображения. ```python from datetime import datetime, timezone from zoneinfo import ZoneInfo utc_now = datetime.now(timezone.utc) tokyo_now = utc_now.astimezone(ZoneInfo("Asia/Tokyo")) print(utc_now) print(tokyo_now) ``` --- ## 3. Вычисления даты/времени: `timedelta` в центре внимания {#sec-5497d843fd3e} ### 3.1 Сложение/вычитание {#sec-0288780aa297} ```python from datetime import datetime, timedelta, timezone now = datetime.now(timezone.utc) print(now + timedelta(days=3)) print(now - timedelta(hours=2)) ``` ### 3.2 Разница между двумя моментами {#sec-c781f333910b} ```python from datetime import datetime, timezone a = datetime(2026, 1, 1, tzinfo=timezone.utc) b = datetime(2026, 1, 10, tzinfo=timezone.utc) delta = b - a print(delta.days) # 9 print(delta.total_seconds()) # 777600.0 ``` ### 3.3 Как воспринимать «период» через `timedelta` {#sec-c81173d2a4f5} `timedelta` работает в днях, секундах и микросекундах. Выражения вроде «через месяц» требуют более сложных подходов (например, `dateutil`), поскольку длина месяца меняется. --- ## 4. Форматирование и разбор: `strftime` / `strptime` {#sec-a17a8e259a48} ### 4.1 datetime → строка (`strftime`) {#sec-8d6f34025b2e} ```python from datetime import datetime, timezone dt = datetime(2026, 1, 30, 14, 5, 0, tzinfo=timezone.utc) print(dt.strftime("%Y-%m-%d %H:%M:%S %z")) ``` Часто используемые шаблоны: * `%Y-%m-%d` – 2026-01-30 * `%H:%M:%S` – 14:05:00 * `%z` – +0000 (смещение UTC) ### 4.2 строка → datetime (`strptime`) {#sec-f2bbc1672485} ```python from datetime import datetime s = "2026-01-30 14:05:00" dt = datetime.strptime(s, "%Y-%m-%d %H:%M:%S") print(dt) ``` Полученный `dt` – **naive**. Чтобы задать часовой пояс, добавляем `tzinfo`. ```python from datetime import datetime, timezone s = "2026-01-30 14:05:00" dt = datetime.strptime(s, "%Y-%m-%d %H:%M:%S").replace(tzinfo=timezone.utc) print(dt) ``` > `replace(tzinfo=...)` не меняет время, а только присваивает метку часового пояса. Для реального преобразования используйте `astimezone()`. --- ## 5. Часовые пояса: различие между `timezone` и `zoneinfo` {#sec-05b1d0f7ef82} ### 5.1 Фиксированное смещение – `timezone` {#sec-67fec65074ab} ```python from datetime import datetime, timezone, timedelta kst_fixed = timezone(timedelta(hours=9)) dt = datetime(2026, 1, 30, 12, 0, tzinfo=kst_fixed) print(dt) ``` ### 5.2 Региональный часовой пояс – `zoneinfo` {#sec-834b663bce83} Для зон с летним временем используйте `zoneinfo`. ```python from datetime import datetime, timezone from zoneinfo import ZoneInfo utc_now = datetime.now(timezone.utc) ny_now = utc_now.astimezone(ZoneInfo("America/New_York")) print(ny_now) ``` ### 5.3 `replace(tzinfo=...)` vs `astimezone(...)` {#sec-35bf0fbaa9df} * `replace(tzinfo=...)` – время остаётся тем же, меняется только метка * `astimezone(...)` – переводит момент во времени в другой часовой пояс Понимание разницы помогает избежать багов. --- ## 6. Частые ошибки {#sec-552ca3933648} ### 6.1 Смешивание naive/aware {#sec-21a4c96b9022} * Для внутренних расчётов лучше использовать **aware (UTC)** * При вводе данных сразу определяйте и нормализуйте часовой пояс ### 6.2 «Локальное время» может отличаться в разных средах {#sec-e2bd08b413c3} `datetime.now()` использует локальные настройки среды. В контейнерах это может быть UTC. Лучше явно указывать `datetime.now(timezone.utc)`. ### 6.3 Несоответствие формата при разборе строк {#sec-e52b753858ac} `strptime` чувствителен к формату: даже один символ разницы приводит к ошибке. Если входные строки могут иметь разные форматы, предварительно нормализуйте их или пробуйте несколько шаблонов. --- ## 7. Три популярных шаблона {#sec-b244af674a6a} ### 7.1 Сохранение в формате ISO 8601 {#sec-4b1979b29466} ```python from datetime import datetime, timezone dt = datetime.now(timezone.utc) print(dt.isoformat()) # пример: 2026-01-30T05:12:34.567890+00:00 ``` ### 7.2 Формирование имени файла с сегодняшней датой {#sec-ae13a5dac423} ```python from datetime import datetime stamp = datetime.now().strftime("%Y%m%d") filename = f"report_{stamp}.json" print(filename) ``` ### 7.3 Вычисление оставшегося времени до заданного момента {#sec-b509d1188ff7} ```python from datetime import datetime, timezone target = datetime(2026, 2, 1, 0, 0, tzinfo=timezone.utc) now = datetime.now(timezone.utc) remaining = target - now print(remaining) print(remaining.total_seconds()) ``` --- ## 8. Итоги {#sec-9fa53305f95a} Модуль `datetime` позволяет не только форматировать даты, но и выполнять надёжные расчёты времени. Включение часовых поясов (`timezone`, `zoneinfo`) делает код устойчивым к различиям среды. В следующей статье мы разберём модуль `random`, включая генерацию случайных чисел, выборки, перемешивание и безопасные случайные значения (`secrets`). --- **Связанные статьи:** - [Как правильно использовать datetime и timezone в Django](/ko/whitedec/2025/11/10/django-datetime-timezone/) - [Магия управления временем в Django – полный гид по `django.utils.timezone`](/ko/whitedec/2025/11/14/django-utils-timezone-guide/) --- **Предыдущие части серии** - [[Python стандартная библиотека - 0] Что такое стандартная библиотека Python? Руководство для новичков](/ko/whitedec/2026/1/29/python-standard-library/) - [[Python стандартная библиотека -1] Файловая система и окружение OS: pathlib vs os](/ko/whitedec/2026/1/29/file-system-os-environment-master-pathlib-vs-os/) - [[Python стандартная библиотека - 2] Хранение данных и сериализация: json, pickle, csv](/ko/whitedec/2026/1/30/python-json-pickle-csv/)