# Работа с датами, временем и временными промежутками.
Работа с датами и временем в любом языке программирования — довольно скользкая штука.
Все эти хитрые високосные года, часовые пояса и т.п. создают бесконечное количество сложностей для программистов.
В питоне для работы с этими объектами в модуле datetime реализованы классы
date — даты в григорианском календаре,
time — времена в рамках одних суток из 24⋅60⋅60 секунд,
datetime — дата, время и часовой пояс вместе,
timedelta — промежуток времени между датами или временами.
tzinfo — информация о часовом поясе. Всё, связанное с часовыми поясами здесь и далее опущено.
Время — это самый «беспомощный» тип.
Создать экземпляр времени можно при помощи команды вида
time(hour=0, minute=0, second=0, microsecond=0),
при этом можно указывать любой набор параметров с исключительно разумными целыми значениями (25 часов или -3 минуты использовать нельзя).
Класс time поддерживает следующие операции:
Операция
Смысл
Пример
t.hour
t.minute
t.second
t.microsecond
Количество часов, минут, секунд и микросекунд во времени
time(13, 45).minute
# 45
t.replace(...)
Создать новую отметку времени, у которой отдельные значения заменены.
date — это даты в предположении, что григорианский календарь действовал всегда.
Создать экземпляр даты можно при помощи команды вида
date(year, month, day),
при этом все параметры обязательны, и должны быть разумным целым числом. -3 месяца или 40 дней не предлагать.
Класс date поддерживает следующие операции:
Операция
Смысл
Пример
d.year
d.month
d.day
Отдельные части даты
date(2020, 2, 29).day
# 29
date.today()
Текущая дата
date.today()
# datetime.date(2019, 1, 3)
date.fromordinal(ordinal)
d.toordinal()
Сделать дату из номера дня, начиная с 0001-01-01, и наоборот.
datetime — это класс, позволяющий работать с датой-временем (timestamp'ом).
Создать экземпляр даты-времени можно при помощи команды вида
datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0),
при этом год, месяц и день — обязательные параметры.
Если параметр передан, то он должен быть разумным целым числом.
Объект типа timedelta возникает при вычитании двух дат или дат-времён.
Также промежуток может быть задана явно:
timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0).
Можно указывать любой набор параметров с любыми разумными целыми и действительными значениями.
Внутри хранятся только дни, секунды и микросекунды, поэтому после создания промежутки времени «нормализуются» так, чтобы использовать
только эти значения.
Поэтому timedelta(microseconds=-1) содержит -1 день, 86399 секунд и 999999 микросекунд.
Умножение на целое или действительное число
При умножении на действительное может возникнуть округление.
Вообще говоря, можно промежутки делить на числа,
а также целочисленно делить на числа
Функция datetime.strptime и метод dt.strftime позволяют собрать дату-время из текстовой строки или
форматировать дату-время в соответствии с шаблоном.
При этом часть шаблонов зависят от локали, которую можно выставить при помощи команд в духе
По заданному числу n
от 1 до 365 определите, на какое число
какого месяца приходится день невисокосного года с номером n.
Программа получает на вход целое число n
и должна вывести
число месяца (от 1 до 31) и название месяца, на которое
приходится данный день.
Решите обратную предыдущей задачу: по записи названия месяца и дня
определите номер дня в году.
Алгоритм решения задачи оформите в виде отдельной функции.
Дата задана в формате dd.mm.yyyy.
Выведите ее в формате "Month d, y",
где Month — английское название месяца,
d — номер дня в месяце, без
лидирующих нулей, y — номер года без лидирующих нулей.
Дата задана в формате dd.mm.yyyy. Выведите
дату, следующую за ней в том же формате. Учтите правило формирования
високосных годов. Следует считать, что григорианский календарь
действовал всегда.
Дата задана в формате dd.mm.yyyy. Выведите дату, предшестующую ей в том
же формате. Учтите правило формирования високосных годов.
Следует считать, что григорианский календарь действовал всегда.
Задан день и месяц рождения в формате
dd.mm. Задана текущая дата в формате dd.mm.yyyy. Определите, сколько
дней осталось до дня рождения. Если сегодня — день рождения, то
необходимо вывести 0.
Часы показывают время в формате hh:mm:ss.
На этих часах запустили таймер, который прозвенит через n секунд.
Определите время, которое будет на часах, когда прозвенит таймер.
Число n может принимать значения от 0 до 109.
Профессор лег спать, когда на часах было время h1:m1:s1, а когда он проснулся было время h2:m2:s2.
Определите, сколько времени спал профессор, если известно, что он проспал не более суток.
Время выведите в формате hh:mm:ss.
Будильник в сотовом телефоне можно настроить так, чтобы
он звонил каждый день в одно и то же время, либо в указанное время в определенный день недели.
Независимо можно настроить несколько будильников.
По информации о будильниках и текущему времени и дню недели определите, когда прозвонит очередной будильник.
В первой строке вводится текущий день недели (число от 1 до 7), затем через пробел,
текущее время в формате HH:MM.
Во второй строке вводится одно натуральное число N, не превосходящее 100 – количество будильников.
В следующих N строках вводится описание N будильников в таком же формате. Значение дня недели,
равное 0, означает, что будильник звонит каждый день.
Выведите номер дня недели и время, когда будильник зазвонит в следующий раз, в таком же формате.