#!/usr/bin/env python
# coding: utf-8
# # Задания для самостоятельного выполнения (блок 3, модули)
#
#
# ## Задание 1
#
# В Python есть удобные инструменты для работы с датами в любом формате. Например, следующие стандартные форматы дат хорошо распознаются стандартными инструментами вроде Excel: `09.05.2019, 2018-12-31`. Но в большинстве случаев даты будут поступать в совершенно любых вариантах. Примеры популярных форматов из баз данных и API:
#
# * `2019-05-09Z15:34:55`;
# * `19 Apr 19, Fri, 01:27:34.112`;
# * `11:34 PM"`.
#
# В каждом из этих примеров надо распознать дату и время — указать системе, где стоит год, где день и секунды.
#
# ### Работа с датами на практике
#
# Даты встречаются в большинстве данных, с которыми вам придётся работать на практике. Рассмотрим одну из таких задач.
#
# Вам приходит ежедневный отчёт по доходам проекта. Как правило, системы, предоставляющие финансовые данные, обновляют эту информацию в течение нескольких дней, то есть данные по доходам за вчерашний день будут немного корректироваться в течение 2-3 дней. В таких случаях хорошей практикой является обновление связанных отчётов не только за вчерашний день, но и за несколько предыдущих. Иначе отчёт будет расходиться с реальными финансовыми показателями.
#
# В таком случае необходимо задавать окно дат за последние несколько дней и запускать формирование отчёта за каждый из них. Например, если сегодня 2 марта, то пересчёт нужно запускать за последние 2 дня февраля и 1 марта. При этом нужно учитывать возможный високосный год. Для решения таких задач в Python есть множество готовых инструментов. Перед тем как познакомиться с ними, рассмотрим очень важный вопрос формата даты и времени.
#
# ### Форматы дат и времени
#
# В жизни мы привыкаем видеть даты в привычных для нас форматах. Например, запись `01.12.18` обычно означает `1 декабря 2018 года`. Однако для жителей США эта дата окажется `12 января 2018 года`, так как для них привычнее сначала указывать номер месяца, а потом день. Excel с настройками для России распознает эту дату как `1 декабря`, а в американской локализации — как `12 января`.
#
# Многие выгрузки из систем и баз данных имеют свой служебный формат. Например, формат времени из разных систем может отличаться:
#
# * `2018-11-09 15:45:21`;
# * `11/09/2018 3:45:20 PM`;
# * `2018-11-09T15:45:21.2984`.
#
# Для всех этих случаев необходимо задавать формат распознавания дат, уметь сравнивать их между собой. Также часто необходимо корректно прибавлять к датам различные временные интервалы. Например, час или день.
#
# ### Формат YYYY-MM-DD
#
# Для распознавания дат в Python введены обозначения, которые помогут системе правильно распознать практически любой формат даты и времени. Для этого необходимо указать в коде, что означает каждая цифра и буква.
#
# Рассмотрим простой пример, когда дата задана в следующем формате:
# In[2]:
date_string = '2019-03-01'
# ### Распознавание дат в Python
#
# Вернемся к переменной `date_string`. Что нужно, чтобы Python начал воспринимать эту строку как дату? Для начала необходимо явно указать, где в этой строке год, месяц и день:
#
# * `2019 — год`;
# * `03 — месяц`;
# * `01 — день`.
#
# А также не забыть, что в такой записи между ними стоят дефисы «-». Для расшифровки даты и времени составлены таблицы:
#
# * [официальная документация](https://docs.python.org/3/library/datetime.html) (таблица внизу страницы по ссылке);
# * [вариант с русским переводом](https://all-python.ru/osnovy/modul-datetime.html) (таблица внизу страницы по ссылке).
# Вместо чисел в переменной `date_string` надо подставить подходящие форматы из таблицы. Начнем с года: в таблице есть два варианта года:
#
# * `%y` — номер года без указания столетия (например, 19 для года 2019);
# * `%Y` — полный вариант записи (2019), который нам подходит.
#
# Подставляем вместо года его формат: `'%Y-03-01'`
#
# Теперь месяц. Видим в таблице три варианта:
#
# * `%b` — сокращенное название месяца вроде Jan, Feb;
# * `%B` — полное название месяца;
# * `%m` — номер месяца в числовом представлении (наш вариант).
#
# Добавляем расшифровку месяца: `'%Y-%m-01'`
#
# Формат даты зависит от регистра: `%m` — номер месяца, а `%M` будет количеством минут.
#
# ### Сложные форматы даты и времени
#
# В Python можно распознать любой тип даты.
#
# Давайте укажем формат даты `2019-04-01T06:30:00 (6:30 утра 1 апреля 2019 года)`. Год, месяц и день мы уже расшифровали — их формат `%Y-%m-%d`.
#
# Далее идёт буква `T`, как и любой символ в дате его надо указать в формате: `%Y-%m-%dT06:30:00`.
#
# Далее идет номер часа: в таблице два варианта:
#
# * `%H` — количество часов в 24-часовом формате;
# * `%I` — количество часов в 12-часовом формате.
#
# Нам подходят оба варианта. Для того, чтобы узнать точный вариант, необходимо выяснить пример даты после полудня. Используем вариант `%H`.
#
# ### Формат unixtime
#
# Популярным форматом записи даты и времени является `unixtime` (также POSIX-время). Это количество секунд, прошедших с полуночи `1 января 1970 года` по часовой зоне UTC. Преимущество данного формата в его простоте: обычно это целое число. Также им удобно считать разницу между двумя датами: это будет разница двух чисел в секундах.
#
# Переводить дату в unixtime и обратно можно с помощью кода на Python или специальных онлайн-сервисов, например, [onlineconversion](http://www.onlineconversion.com/unix_time.htm). На этом сайте используется американский формат ввода дат: сначала указывается месяц, потом день.
#
# ### Упражнения
# Вам предложены значения даты и времени, записанные в различных форматах: расшифруйте их. Будьте внимательны при указании формата часа.
#
# Пример задания:
#
# `2019-01-01 (1 января 2019 года)`
#
# Верный ответ:
#
# `%Y-%m-%d`
# ### Упражнение 1
#
# 12.23.2018
#
# (23 декабря 2018 года)
# In[3]:
# здесь решение
# ### Упражнение 2
#
# 01.13.2019Z15:39:01
#
# (13 января 2019 года, 15 часов 39 минут 1 секунда)
# In[4]:
# здесь решение
# ### Упражнение 3
#
# 23:45
#
# (23 часа 45 минут)
# In[5]:
# здесь решение
# ### Библиотека datetime
#
# Теперь, когда мы научились работать с форматами даты и времени в Python, можно познакомиться с библиотеками, которые позволяют получать массу полезной информации из этих данных. Начнем с небольшого замечания об импорте библиотеки `datetime`, который можно сделать двумя способами. Можно импортировать ее в код так:
# In[6]:
import datetime
# На текущем занятии мы будем использовать из этой библиотеки следующие модули:
#
# * `datetime` для распознавания формата дат,
# * `timedelta` для прибавления к текущей дате определенного временного интервала.
#
# Импортируем эти модули следующим образом:
# In[7]:
from datetime import datetime, timedelta
# Это избавит нас от необходимости писать `datetime.` перед каждым вызовом модулей.
# ### Перевод строки в дату
#
# До этого шага мы работали с датами как с обычными строками. Пора начать использовать полученные знания для практических задач, а именно переводить дату в виде строки в переменную типа `datetime`. Это позволит нам использовать многочисленные возможности работы с датами: выделять из даты любой период (день, секунду), прибавлять и вычитать временные интервалы (например, вычитать из 1 марта 1 день с учетом високосных годов) и многое другое.
#
# Возьмём строку:
# In[8]:
date_string = '05.05.2019 21:00'
# Для перевода этой строки в дату используется метод `strptime`:
# In[9]:
dt = datetime.strptime(date_string, '%d.%m.%Y %H:%M')
dt
# Мы получили переменную типа `datetime`, и в качестве первого действия можно сразу получить год, день, час и другие характеристики даты и времени:
# In[10]:
dt.hour
# ### Перевод даты в строку
#
# Перед тем, как рассматривать другие практические применения типа переменных `datetime`, рассмотрим обратный процесс перевода даты в строку. Эта операция будет часто встречаться, так как результаты работы с датами обычно записываются в файлы как строки в удобном формате. Для этого действия предназначен метод `strftime`, который похож на `strptime` из прошлого шага.
#
# Зададим значение `dt` из прошлого шага ещё раз, не обязательно для этого использовать перевод из строки, можно задать дату и время напрямую:
# In[11]:
dt = datetime(2019, 5, 5, 21, 0)
# Как видно из синтаксиса, порядок следования периодов логичен: год, номер месяца, день, часы, минуты, секунды (не обязательно указывать все аргументы, но важно сохранять их порядок). Теперь для перевода даты `dt` в строку достаточно указать желаемый формат. Используем стандартный формат `YYYY-MM-DD`:
# In[12]:
dt.strftime('%Y-%m-%d')
# ### Упражнение 4
# Дана строка с датой `date_string = '2019-07-07T18:59:33'`
#
# Преобразуйте ее в строку с форматом `%d.%m.%Y`. Результат запишите в переменную `date_format`
# In[13]:
from datetime import datetime
date_string = '2019-07-07T18:59:33'
# здесь решение
# ## Задание 2
#
# В блокнотах CoLab можно вычислять время выполнения инструкций:
# In[14]:
get_ipython().run_line_magic('timeit', '456**3')
# Определите время вычисления произвольных инструкций.
# In[ ]:
# здесь код