{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 📅 Модуль `datetime` в Python: применение с `pandas`\n",
    "\n",
    "## 🚀 Преимущество `datetime` перед `pandas.Timestamp` и `pandas.Timedelta`\n",
    "\n",
    "Хотя `pandas` предлагает мощные инструменты для работы с временем (`Timestamp`, `Timedelta`, `DatetimeIndex`), стандартный модуль `datetime` имеет ряд **ключевых преимуществ**:\n",
    "\n",
    "| Критерий | `datetime` (стандартный) | `pandas.Timestamp` / `Timedelta` |\n",
    "|----------|--------------------------|----------------------------------|\n",
    "| **Установка** | ✅ Встроен в Python (batteries included) | ❌ Требует `pip install pandas` |\n",
    "| **Скорость одиночных операций** | ✅ Быстрее (нет обёрток) | ⚠️ Медленнее из-за overhead |\n",
    "| **Память** | ✅ Легковесный | ❌ Тяжелее |\n",
    "| **Гибкость часовых зон** | ✅ `zoneinfo` (Python 3.9+) — полная IANA-база | ⚠️ Ограниченная поддержка |\n",
    "| **Совместимость** | ✅ Работает везде, где есть Python | ⚠️ Требует pandas |\n",
    "| **Векторные операции** | ❌ Только поэлементно | ✅ Оптимизирован для массивов |\n",
    "\n",
    "### 💡 Вывод:\n",
    "> **Используй `datetime`**, когда работаешь с одиночными датами, часовыми зонами или в средах без `pandas`.\n",
    "> **Используй `pandas`**, когда обрабатываешь **большие таблицы** (миллионы строк) — там он в разы быстрее благодаря векторизации.\n",
    "\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 📚 Часть 1. Теория: модуль `datetime`\n",
    "\n",
    "Модуль `datetime` содержит **5 основных классов**:\n",
    "\n",
    "1. **`date`** — только дата (год, месяц, день)\n",
    "2. **`time`** — только время (часы, минуты, секунды, микросекунды)\n",
    "3. **`datetime`** — дата + время\n",
    "4. **`timedelta`** — разница между двумя датами/временами\n",
    "5. **`timezone`** — часовой пояс (фиксированное смещение от UTC)\n",
    "\n",
    "С Python 3.9+ также доступен модуль **`zoneinfo`** для работы с полноценными часовыми зонами (IANA)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from datetime import date, time, datetime, timedelta, timezone\n",
    "import pandas as pd\n",
    "\n",
    "print('Модули загружены ✅')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 🔹 1.1. Класс `date` — работа с датой"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Сегодняшняя дата\n",
    "today = date.today()\n",
    "print('Сегодня:', today)\n",
    "print('Год:', today.year, '| Месяц:', today.month, '| День:', today.day)\n",
    "\n",
    "# Создание конкретной даты\n",
    "my_birthday = date(2009, 5, 15)\n",
    "print('День рождения:', my_birthday)\n",
    "\n",
    "# День недели (0 = понедельник, 6 = воскресенье)\n",
    "print('День недели:', today.weekday())  # 0-6\n",
    "print('ISO день недели:', today.isoweekday())  # 1-7"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 🔹 1.2. Класс `time` — работа с временем"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Конкретное время\n",
    "lesson_start = time(9, 0, 0)  # 09:00:00\n",
    "lesson_end = time(10, 30, 0)  # 10:30:00\n",
    "\n",
    "print('Урок начинается:', lesson_start)\n",
    "print('Урок заканчивается:', lesson_end)\n",
    "print('Час:', lesson_start.hour, '| Минуты:', lesson_start.minute)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 🔹 1.3. Класс `datetime` — дата и время вместе"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Текущие дата и время\n",
    "now = datetime.now()\n",
    "print('Сейчас:', now)\n",
    "\n",
    "# UTC время\n",
    "utc_now = datetime.utcnow()\n",
    "print('UTC:', utc_now)\n",
    "\n",
    "# Парсинг строки в datetime\n",
    "date_str = '2026-11-09 14:30:00'\n",
    "parsed = datetime.strptime(date_str, '%Y-%m-%d %H:%M:%S')\n",
    "print('Распарсили строку:', parsed)\n",
    "\n",
    "# Форматирование datetime в строку\n",
    "formatted = now.strftime('%d.%m.%Y %H:%M')\n",
    "print('Отформатировали:', formatted)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 🔹 1.4. Класс `timedelta` — разница во времени"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Создаём промежуток времени\n",
    "week = timedelta(weeks=1)\n",
    "day = timedelta(days=1)\n",
    "hour = timedelta(hours=1)\n",
    "\n",
    "print('Через неделю:', now + week)\n",
    "print('Завтра:', now + day)\n",
    "print('Через час:', now + hour)\n",
    "\n",
    "# Разница между датами\n",
    "new_year = datetime(2027, 1, 1)\n",
    "diff = new_year - now\n",
    "print(f'До Нового года: {diff.days} дней, {diff.seconds // 3600} часов')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 🔹 1.5. Часовые зоны (`timezone` и `zoneinfo`)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from zoneinfo import ZoneInfo\n",
    "\n",
    "# Москва (UTC+3)\n",
    "msk = datetime.now(ZoneInfo('Europe/Moscow'))\n",
    "print('Москва:', msk)\n",
    "\n",
    "# Нью-Йорк\n",
    "ny = datetime.now(ZoneInfo('America/New_York'))\n",
    "print('Нью-Йорк:', ny)\n",
    "\n",
    "# Токио\n",
    "tokyo = datetime.now(ZoneInfo('Asia/Tokyo'))\n",
    "print('Токио:', tokyo)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## 🛠️ Часть 2. Практика: базовые задачи\n",
    "\n",
    "### Задача 1. Возраст\n",
    "Вычисли, сколько тебе лет (полных лет) на сегодняшний день."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Реши задачу здесь\n",
    "birthday = date(2009, 5, 15)  # подставь свою дату\n",
    "today = date.today()\n",
    "\n",
    "# ТВОЙ КОД ↓\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Задача 2. День недели\n",
    "Определи, какой день недели был 9 ноября 2026 года (сегодня)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "target = date(2026, 11, 9)\n",
    "days = ['Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота', 'Воскресенье']\n",
    "\n",
    "# ТВОЙ КОД ↓\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Задача 3. Сколько дней до события\n",
    "Посчитай, сколько дней осталось до твоего следующего дня рождения."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "birthday = date(2009, 5, 15)\n",
    "today = date.today()\n",
    "\n",
    "# Подсказка: нужно создать дату ДР в текущем или следующем году\n",
    "# ТВОЙ КОД ↓\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## 🧠 Часть 3. Практика повышенного уровня: `datetime` + `pandas`\n",
    "\n",
    "Здесь мы покажем, как **объекты `datetime` интегрируются с `pandas`** и почему это важно."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 🔥 Задача 4. Создание DataFrame с `datetime`-объектами\n",
    "\n",
    "Создай DataFrame с расписанием уроков, используя **стандартные `datetime`-объекты** (не строки!)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "schedule = [\n",
    "    {'lesson': 'Математика', 'start': datetime(2026, 11, 9, 9, 0), 'end': datetime(2026, 11, 9, 9, 45)},\n",
    "    {'lesson': 'Информатика', 'start': datetime(2026, 11, 9, 10, 0), 'end': datetime(2026, 11, 9, 10, 45)},\n",
    "    {'lesson': 'Физика', 'start': datetime(2026, 11, 9, 11, 0), 'end': datetime(2026, 11, 9, 11, 45)},\n",
    "    {'lesson': 'Английский', 'start': datetime(2026, 11, 9, 12, 0), 'end': datetime(2026, 11, 9, 12, 45)},\n",
    "]\n",
    "\n",
    "df = pd.DataFrame(schedule)\n",
    "print(df)\n",
    "print('\\nТипы данных:')\n",
    "print(df.dtypes)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 🔥 Задача 5. Вычисление длительности уроков через `timedelta`\n",
    "\n",
    "Добавь столбец `duration`, содержащий длительность урока в минутах. Используй **стандартный `timedelta`**."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# ТВОЙ КОД ↓\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 🔥 Задача 6. Конвертация в `pandas.Timestamp` (и зачем это нужно)\n",
    "\n",
    "Покажи разницу в скорости между `datetime` и `pd.Timestamp` при обработке большого массива данных."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import time\n",
    "\n",
    "# Генерируем 1 миллион строк\n",
    "N = 1_000_000\n",
    "dates_str = ['2026-11-09'] * N\n",
    "\n",
    "# Способ 1: через datetime.strptime (медленно)\n",
    "start = time.time()\n",
    "dates_dt = [datetime.strptime(d, '%Y-%m-%d') for d in dates_str]\n",
    "t1 = time.time() - start\n",
    "print(f'datetime.strptime: {t1:.3f} сек')\n",
    "\n",
    "# Способ 2: через pd.to_datetime (быстро!)\n",
    "start = time.time()\n",
    "dates_pd = pd.to_datetime(dates_str)\n",
    "t2 = time.time() - start\n",
    "print(f'pd.to_datetime:    {t2:.3f} сек')\n",
    "\n",
    "print(f'\\n🚀 pandas быстрее в {t1/t2:.1f} раз!')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 🔥 Задача 7. Временной ряд с часовыми зонами\n",
    "\n",
    "Создай DataFrame с временем запуска роботов в разных странах. Используй `zoneinfo` для корректной работы с часовыми зонами."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "robots = [\n",
    "    {'robot': 'R2D2', 'country': 'Russia', 'tz': 'Europe/Moscow', 'launch': datetime(2026, 11, 9, 10, 0)},\n",
    "    {'robot': 'C3PO', 'country': 'USA', 'tz': 'America/New_York', 'launch': datetime(2026, 11, 9, 10, 0)},\n",
    "    {'robot': 'WALL-E', 'country': 'Japan', 'tz': 'Asia/Tokyo', 'launch': datetime(2026, 11, 9, 10, 0)},\n",
    "    {'robot': 'BB-8', 'country': 'UK', 'tz': 'Europe/London', 'launch': datetime(2026, 11, 9, 10, 0)},\n",
    "]\n",
    "\n",
    "df_robots = pd.DataFrame(robots)\n",
    "\n",
    "# ТВОЙ КОД ↓\n",
    "# Привяжи каждому роботу его часовой пояс (локализуй launch)\n",
    "# Затем переведи все запуски в UTC и сравни, какой робот стартовал раньше всех\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 🔥 Задача 8. Анализ временных данных (повышенный уровень)\n",
    "\n",
    "Дан DataFrame с логами работы сервера. Найди:\n",
    "1. Сколько часов работал сервер в каждый день\n",
    "2. Самый длинный непрерывный аптайм\n",
    "3. Среднее время между сбоями"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "logs = [\n",
    "    {'event': 'start', 'time': datetime(2026, 11, 1, 8, 0)},\n",
    "    {'event': 'crash', 'time': datetime(2026, 11, 1, 14, 30)},\n",
    "    {'event': 'start', 'time': datetime(2026, 11, 1, 14, 35)},\n",
    "    {'event': 'start', 'time': datetime(2026, 11, 2, 9, 0)},\n",
    "    {'event': 'crash', 'time': datetime(2026, 11, 2, 18, 0)},\n",
    "    {'event': 'start', 'time': datetime(2026, 11, 3, 10, 0)},\n",
    "]\n",
    "\n",
    "df_logs = pd.DataFrame(logs)\n",
    "\n",
    "# ТВОЙ КОД ↓\n",
    "# Подсказка: используй timedelta для вычисления разниц между событиями\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## 🎯 Итоги\n",
    "\n",
    "### Когда использовать что:\n",
    "\n",
    "| Ситуация | Инструмент |\n",
    "|----------|-----------|\n",
    "| Одиночная дата/время | `datetime` |\n",
    "| Часовые зоны | `datetime` + `zoneinfo` |\n",
    "| Таблица с 10 строками | `datetime` (проще) |\n",
    "| Таблица с 1 000 000 строк | `pd.to_datetime` (быстрее) |\n",
    "| Векторные операции | `pandas` |\n",
    "| Скрипт без зависимостей | `datetime` |\n",
    "\n",
    "### 📌 Главное правило:\n",
    "> **`datetime` — это фундамент. `pandas` — это надстройка для больших данных.**\n",
    "> Понимай оба — и выбирай инструмент под задачу!"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.11.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
