Курс по стандартной библиотеке: https://stepik.org/a/259466?utm_source=proproprogs
Продолжаем
рассматривать основные принципы работы объектов класса datetime.date. На этом
занятии увидим, как с его помощью можно выполнять различные арифметические вычисления
с датами.
Пусть, например,
имеются два объекта для текущего и предыдущего дней:
today = datetime.date.today()
yesterday = today.replace(day=today.day-1)
Тогда на их
основе можно вычислить разницу между сегодняшним и вчерашним днем:
delta = today - yesterday
print(delta) # 1 day, 0:00:00
Полученный
результат (один день) будет сохранен в объекте delta типа timedelta. Объекты этого
класса часто используются в операциях с календарными датами. Например, мы бы
хотели создать объект yesterday путем вычитания одного дня из
объекта today:
yesterday = today - 1 # ошибка
Но такая
операция приведет к ошибке, т.к. арифметические операции с обычными
целочисленными значениями недопустимы. Это связано с тем, что непонятно как
интерпретировать число 1: как день, или как год, или как месяц или что-то еще.
Поэтому разработчики модуля добавили еще один класс timedelta, с которым
можно выполнять подобные вычисления с датами:
yesterday = today - datetime.timedelta(days=1)
Вообще объекты
класса datetime.timedelta описывают
именно интервалы времени, то есть разницы между двумя моментами времени.
Интервал может выражаться в неделях, днях, секундах и микросекундах. Поэтому
объекты этого класса конструируются согласно синтаксису:
timedelta([days[,
seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]])
Например:
zero = timedelta() # нулевой интервал
one_day = timedelta(days=1)
one_week = timedelta(weeks=1)
last_week = timedelta(weeks=-1)
two_last_hours = timedelta(hours=-2)
dt = timedelta(days=5, hours=6, milliseconds=10)
Как видите,
интервалы могут содержать отрицательные значения. И обратите внимание на
разницу определения следующих объектов:
one_day = timedelta(days=1) # один день
first_day = datetime.date(year=1, day=1, month=1) # дата: 0001-01-01
Поэтому когда
нам нужен именно временной интервал, то удобно использовать объекты класса timedelta.
Объекты класса timedelta содержат
следующие полезные свойства, доступные только для чтения:
days = one_week.days # 7
seconds = one_week.seconds # 0
microseconds = one_week.microseconds # 0
Обратите
внимание, что свойств weeks, months и подобных не существует,
только дни, секунды и микросекунды. Причем все эти три свойства работают в
сочетании друг с другом. Поэтому для одной недели будет 7 дней и 0 секунд. А
вот, например, для такого интервала:
td = timedelta(weeks=1, hours=12)
получим:
days = td.days # 7
seconds = td.seconds # 43200
microseconds = td.microseconds # 0
Если же нам
нужно узнать общее число секунд в заданном интервале, то можно воспользоваться
методом total_seconds():
sc = td.total_seconds() # 648000.0
Арифметика с интервалами и датами
На основе
существующих интервалов мы можем создавать новые путем выполнения арифметических
операций с ними. Например, на основе интервала one_day можно
сформировать еще несколько следующим образом:
twodays = 2 * one_day
half_day = one_day / 2
three_days = one_day + two_days
one_and_half_day = one_day * 1.5
Обратите
внимание, что объекты класса date можно только вычитать между собой:
today = datetime.date.today()
yesterday = today - one_day
t = today - yesterday
вычисляя
временные интервалы в виде объектов класса timedelta. А вот с
объектами timedelta можно выполнять
операции и вычитания и сложения. Пусть, например, у нас заданы интервалы в один
день и одну неделю, а также дата в виде текущего дня:
one_day = timedelta(days=1)
one_week = timedelta(weeks=1)
today = datetime.date.today()
На их основе достаточно
просто можно вычислить следующие даты:
yesterday = today - one_day
tomorrow = today + one_day
last_week = today - one_week
next_week = today + one_week
Видите, как это
удобно и наглядно записано в тексте программы. Каждый программист легко поймет,
что здесь вычисляется.
Конечно, другие
арифметические операции с объектами date и timedelta выполнять нельзя,
только складывать и вычитать. Например, следующие команды приведут к ошибкам:
t = today * one_day
t = today / one_day
Сравнение интервалов и дат
С объектами
классов date и timedelta можно выполнять
операции сравнения. Например, такие:
one_day < one_week # True
one_day == one_week # False
today <= yesterday # False
today > yesterday # True
last_week != next_week # True
То есть, здесь
можно использовать все стандартные операции сравнения. Но только с объектами
одного и того же типа. Например, следующие команды приведут к ошибкам:
today < one_day # TypeError
one_week >= next_week # TypeError
Хотя операции
сравнения на равенство и неравенство, формально, сработают:
one_week == next_week # False
но в них нет
особого смысла, т.к. интервалы времени и конкретная дата – разные сущности.
В заключение
этого занятия приведу один простой практический пример с использованием дат и
их сравнений:
from datetime import datetime
expiration_date = datetime(2025, 8, 15)
today = datetime.now()
if expiration_date > today:
remaining_time = expiration_date - today
print(f"Продукт годен. Осталось {remaining_time.days} дней.")
else:
print("Срок годности истек!")
Здесь
проверяется срок годности некоторого продукта с помощью операции сравнения дат.
Если продукт еще годен, то вычисляется число оставшихся дней. Иначе, выводится
сообщение "Срок годности истек!".
Курс по стандартной библиотеке: https://stepik.org/a/259466?utm_source=proproprogs