Изменение цен на нефть со временем, изменение температуры за день, уровень цен за месяц, доходы за год — все эти компоненты объединяет время. В Data Science часто приходится сталкиваться с временными рядами. Сегодня мы расскажем о стандартных модулях Python, которые предоставляют интерфейс для дат и времени: time, datetime, calendar.
3 основных модуля
В комплекте стандартных библиотек Python имеются три основных модуля для работы со временем, датами и календарем:
time
предоставляет различные функции для управления значениями времени;datetime
поможет для работы с датами;calendar
обеспечит идеализированным григорианским календарем.
Далее мы рассмотрим, как их можно использовать в реальных проектах Data Science и повседневных задачах Python-программиста.
Модуль time для отсчета времени
Время в Python отсчитывается в секундах от начала эпохи. Эпоха может отличаться для разных операционных систем. Для Unix-систем эпоха — это январь 1970 года 00:00:00. Чтобы узнать, какая эпоха на компьютере, используется функция time.gmtime(0)
:
>>> import time >>> time.gmtime(0) time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0)
Возвращается объект time_struct
, который имеет атрибуты в виде года, месяца, недели и т.д. Последний атрибут tm_isdst показывает летнее ли время (0 — нет, 1- да).
Считаем время в Python
Чтобы узнать, сколько прошло секунд с эпохи до настоящего времени, в Python используется функция time
:
>>> time.time() 1598423943.4023273
Можно получить объект time_struct
с нынешним временем в вашем часовом поясе, для этого есть localtime
:
>>> time.localtime() time.struct_time(tm_year=2020, tm_mon=8, tm_mday=26, tm_hour=13, tm_min=39, tm_sec=43, tm_wday=2, tm_yday=239, tm_isdst=0)
Получить полный форматированный вариант в читаемом виде поможет функция time.asctime()
:
>>> time.asctime() 'Wed Aug 26 13:51:33 2020'
Более удобный формат времени
Функция asctime
возвращает полную информацию о времени в определенном формате. Когда требуется самостоятельно задать формат вывода, в Python можно воспользоваться функцией strftime
, которая принимает формат вывода и объект time_struct
:
>>> time.strftime("%a %d %Y", time.localtime()) 'Wed 26 2020'
Здесь %a означает день недели, %d — день месяца, а %Y — год. Полный список доступен в официальной документации.
Из строки в time_stuct
А вот получить из строки (str) соответствующий объект time_struct
можно с помощью функции strptime:
>>> time.strptime("Wed 26 2020", "%a %d %Y") time.struct_time(tm_year=2020, tm_mon=1, tm_mday=26, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=26, tm_isdst=-1)
Не стоит путать с strftime
, так как они различаются на одну букву.
Засыпаем на некоторое время
Иногда требуется сымитировать действие, которое занимает определенное время. На помощь придет функция sleep, которая аргументом принимает секунды:
>>> def timeit(secs): ... start = time.time() ... time.sleep(secs) # заснуть на secs ... end = time.time( ... return end - start ... >>> timeit(1) 1.0011100769042969
Работаем с датами
Интерфейс для дат в Python можно найти в модуле datetime
. У него есть 3 основных класса: date
, time
и datetime
— для работы с только датами, только временем и с датой и временем, соответственно. Объект date принимает в качестве аргументов год, месяц и день:
>>> from datetime import date, time, datetime >>> date(year=2020, month=1, day=15) datetime.date(2020, 1, 15)
Объект time
принимает часы, минуты и секунды:
>>> time(hour=18, minute=45, second=30) datetime.time(18, 45, 30)
Объект datetime
принимает все вышеперечисленное:
>>> datetime(year=2020, month=1, day=15, hour=18, minute=45, second=30) datetime.datetime(2020, 1, 15, 18, 45, 30)
Сейчас и сегодня
В Python можно получить сегодняшнюю дату:
>>> date.today() datetime.date(2020, 8, 26)
А также, текущую дату и время:
>>> datetime.today() datetime.datetime(2020, 8, 26, 15, 52, 39, 757438)
Получаем даты из ISO-формата
Помимо прочего, можно получить дату из ISO формат с видом YYYY-MM-DD:
>>> date.fromisoformat("2020-01-15") datetime.date(2020, 1, 15)
В Python 8 был добавлен метод fromisocalendar
, который принимает в качестве аргументов год, неделю, месяц:
>>> date.fromisocalendar(2020, 45, 3) datetime.date(2020, 11, 4)
Формат даты из строки
Как и время из модуля time, объект datetime
имеет методы strptime
и strftime
для получение строки из даты и наоборот:
>>> datetime.strptime("Wed 26 2020", "%a %d %Y") datetime.datetime(2020, 1, 26, 0, 0) >>> today = datetime.today() >>> today.strftime("%a %d %Y") 'Wed 26 2020'
Из секунд в даты
Как уже было сказано, time.time
возвращает количество секунд, которые начинаются с эпохи. Эти секунды также можно перевести в дату и время:
>>> now = time.time() >>> datetime.fromtimestamp(now) datetime.datetime(2020, 8, 26, 13, 39, 3, 402327)
Сколько времени прошло
В Python-модуле datetime
имеется специальный объект timedelta
, который используется для разницы между датами
>>> from datetime import timedelta >>> timedelta(days=10, seconds=25) datetime.timedelta(days=10, seconds=25)
Например, можно получить разницу между сегодняшним и вчерашним днями:
>>> today = datetime.today() >>> yesterday = date(2020, 8, 25) >>> today - yesterday datetime.timedelta(days=1)
Для более точного подсчета можно добавить часы, минуты, секунды.
Работаем с календарем
В Python также можно работать с календарем, который есть в модуле calendar
. Объект Calendar позволяет итерировать дни и недели в месяце, в году и т.д. Например, метод monthdatescalendar
вернет список дней (объекты datetime
) заданного месяца и года, причем дополнит их так, чтобы начинался с первого дня понедельника прошлого месяца и заканчивался последним воскресенья следующего (для августа 2020 — это 27 июля и 6 сентября):
>>> from calendar import Calendar >>> c = Calendar() >>> c.monthdatescalendar(2020, 8) [datetime.date(2020, 7, 27), datetime.date(2020, 7, 28), ... datetime.date(2020, 8, 1), datetime.date(2020, 8, 2), ... datetime.date(2020, 8, 31), ... datetime.date(2020, 9, 6)]
А вот метод yeardatescalendar
вернет список дней заданного года. И в этом случае он будет каждый месяц дополнять днями первого понедельника и последнего воскресенья, поэтому если требуется посчитать количество дней в году лучше использовать функцию max
для месяца, а не len
.
В Python 3.7 были добавлены методы, которые возвращают не список, а генератор (о них мы писали тут). Поэтому вместо monthdatescalendar
можно использовать itermonthdays
.
Печатаем календарь на месяц
В Python можно получить календарь в читаемом формате с помощью prmonth:
>>> import calendar >>> calendar.prmonth(2020, 8) August 2020 Mo Tu We Th Fr Sa Su 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
Печатаем календарь на год
А вот функция prcal
напечатает весь календарь заданного года:
>>> calendar.prcal(2020) January February March Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su 1 2 3 4 5 1 2 1 6 7 8 9 10 11 12 3 4 5 6 7 8 9 2 3 4 5 6 7 8 13 14 15 16 17 18 19 10 11 12 13 14 15 16 9 10 11 12 13 14 15 20 21 22 23 24 25 26 17 18 19 20 21 22 23 16 17 18 19 20 21 22 27 28 29 30 31 24 25 26 27 28 29 23 24 25 26 27 28 29 30 31 ...остальные месяцы
Дни недели
Что не перечислять дни недели самостоятельно (Monday, Tuesday и т.д), можно использовать готовые перечисления. Также с функцией weekday можно узнать день недели заданного дня:
>>> calendar.WEDNESDAY 2 >>> calendar.weekday(2020, 8, 26) 2
Еще больше подробностей вы сможете о работе со временем, датами и временными рядами в целом, вы узнаете на наших Python-курсах в лицензированном учебном центре обучения и повышения квалификации IT-специалистов в Москве.