pgm33 — Введение в ООП. Классы date, time, datetime
Работа с датами, временем и временными промежутками.
Работа с датами и временем в любом языке программирования — довольно скользкая штука.
Все эти хитрые високосные года, часовые пояса и т.п. создают бесконечное количество сложностей для программистов.
В питоне для работы с этими объектами в модуле datetime реализованы классы
date — даты в григорианском календаре,
time — времена в рамках одних суток из $24\cdot60\cdot60$ секунд,
datetime — дата, время и часовой пояс вместе,
timedelta — промежуток времени между датами или временами.
tzinfo — информация о часовом поясе. Всё, связанное с часовыми поясами здесь и далее опущено.
time
Время — это самый «беспомощный» тип.
Создать экземпляр времени можно при помощи команды вида
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 — это даты в предположении, что григорианский календарь действовал всегда.
Создать экземпляр даты можно при помощи команды вида
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
Объект типа 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) и название месяца, на которое
приходится данный день.
Решите обратную предыдущей задачу: по записи названия месяца и дня
определите номер дня в году.
Алгоритм решения задачи оформите в виде отдельной функции.
January 1
1
December 31
365
IDE
C: Перевод формата даты — 1
Дата задана в формате dd.mm.yyyy.
Выведите ее в формате "Month d, y",
где Month — английское название месяца,
d — номер дня в месяце, без
лидирующих нулей, y — номер года без лидирующих нулей.
12.10.2008
October 12, 2008
01.01.0001
January 1, 1
IDE
D: Перевод формата даты — 2
Решите обратную задачу.
October 12, 2008
12.10.2008
January 1, 1
01.01.0001
IDE
E: Tomorrow
Дата задана в формате dd.mm.yyyy. Выведите
дату, следующую за ней в том же формате. Учтите правило формирования
високосных годов. Следует считать, что григорианский календарь
действовал всегда.
12.10.2008
13.10.2008
31.12.2008
01.01.2009
IDE
F: Yesterday
Дата задана в формате dd.mm.yyyy. Выведите дату, предшестующую ей в том
же формате. Учтите правило формирования високосных годов.
Следует считать, что григорианский календарь действовал всегда.
13.10.2008
12.10.2008
01.01.2009
31.12.2008
IDE
G: Разница дат
Две даты заданы в формате dd.mm.yyyy,
каждая дата — в новой строке. Определите количество дней между этими
датами. Вторая дата больше первой.
01.01.0001
02.01.0001
1
29.02.2004
01.03.2005
366
IDE
H: День недели
Дата задана в формате dd.mm.yyyy. Выведите название дня недели, на который приходится эта дата.
12.10.2008
Sunday
13.10.2008
Monday
IDE
I: День рождения
Задан день и месяц рождения в формате
dd.mm. Задана текущая дата в формате dd.mm.yyyy. Определите, сколько
дней осталось до дня рождения. Если сегодня — день рождения, то
необходимо вывести 0.
19.04
19.04.2002
0
05.05
19.04.2002
16
29.02
28.02.2001
1096
IDE
J: Номер дня по дате
Пронумеруем все даты подряд, считая, что 01.01.0001 имеет номер 1,
02.01.0001 — номер 2 и т.д. По заданной дате определите ее порядковый номер.
Программа получает на вход число дат \(N\le 200000\),
затем заданы \(N\) дат. Для каждой из них выведите ее порядковый номер.
2
01.01.0001
01.01.0002
1
366
IDE
K: Дата по номеру дня
Решите обратную задачу: определите дату по номеру дня.
2
1
366
01.01.0001
01.01.0002
IDE
L: Разница дат — 2
Научитесь быстро вычислять разницу между двумя датами.
Программа получает на вход число N, не превосходящее 105.
Далее идет 2N дат, при этом не гарантируется, что первая дата меньше второй.
Выведите N чисел: для каждой пары дат входного файла выведите их разность
(которая может быть как положительной, так и отрицательной).
2
01.01.0001
02.01.0001
01.03.2005
29.02.2004
1
-366
IDE
Время
M: Количество секунд
Часы показывают время в формате hh:mm:ss.
Определите количество секунд, которое прошло с начала суток.
00:01:01
61
IDE
N: Таймер
Часы показывают время в формате hh:mm:ss.
На этих часах запустили таймер, который прозвенит через n секунд.
Определите время, которое будет на часах, когда прозвенит таймер.
Число n может принимать значения от 0 до 109.
09:00:00
90
09:01:30
23:59:59
1
00:00:00
IDE
O: Разница времен
Профессор лег спать, когда на часах было время h1:m1:s1, а когда он проснулся было время h2:m2:s2.
Определите, сколько времени спал профессор, если известно, что он проспал не более суток.
Время выведите в формате hh:mm:ss.
14:00:00
21:10:30
07:10:30
22:00:00
07:00:00
09:00:00
IDE
P: Будильники
Будильник в сотовом телефоне можно настроить так, чтобы
он звонил каждый день в одно и то же время, либо в указанное время в определенный день недели.
Независимо можно настроить несколько будильников.
По информации о будильниках и текущему времени и дню недели определите, когда прозвонит очередной будильник.
В первой строке вводится текущий день недели (число от 1 до 7), затем через пробел,
текущее время в формате HH:MM.
Во второй строке вводится одно натуральное число N, не превосходящее 100 – количество будильников.
В следующих N строках вводится описание N будильников в таком же формате. Значение дня недели,
равное 0, означает, что будильник звонит каждый день.
Выведите номер дня недели и время, когда будильник зазвонит в следующий раз, в таком же формате.