Даты, времена и календари в Python

Изменение цен на нефть со временем, изменение температуры за день, уровень цен за месяц, доходы за год — все эти компоненты объединяет время. В Data Science часто приходится сталкиваться с временными рядами. Сегодня мы расскажем о стандартных модулях Python, которые предоставляют интерфейс для дат и времени: time, datetime, calendar.

3 основных модуля

В комплекте стандартных библиотек Python имеются три основных модуля для работы со временем, датами и календарем:

  1. time предоставляет различные функции для управления значениями времени;
  2. datetime поможет для работы с датами;
  3. 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-специалистов в Москве.

Добавить комментарий

Поиск по сайту