timedelta
— это класс из модуля datetime
в Python, предназначенный для представления разницы между двумя датами или временем. Он позволяет удобно выполнять операции с датами, такие как сложение или вычитание временных интервалов. Основные параметры, с которыми работает timedelta
, включают дни, часы, минуты, секунды и микросекунды.
Создание объекта timedelta
возможно с использованием различных аргументов. Например, timedelta(days=5)
создаст интервал в пять дней, а timedelta(hours=2, minutes=30)
— интервал длиной в два часа и тридцать минут.
Данный класс поддерживает арифметические операции, что позволяет легко манипулировать датами. Можно прибавить интервал к объекту datetime, используя оператор +, или вычесть, используя оператор -. В результате, timedelta делает работу с датами более интуитивной и эффективной. Кроме того, через методы total_seconds() и другие, возможно извлечь детальные данные о временном промежутке, что значительно облегчает разработку временноориентированных приложений.
Импортируйте класс из модуля datetime
from datetime import timedelta
Для создания экземпляра timedelta
взгляните на строку ниже, она взята из документации
timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)
В ней представлены все возможные аргументы, которые можно передать в объект timedelta
. Все аргументы являются необязательными и по умолчанию равны 0
, вы можете передать любой из них для создания timedelta
. Значения аргументов могут быть типа int или float, а также могут быть положительными или отрицательными.
days
- день,
seconds
- секунды,
microseconds
- микросекунды,
milliseconds
- миллисекунды,
minutes
- минуты,
hours
- часы,
weeks
- недели.
Так как все аргументы в timedelta
необязательные передавайте их по имени:
from datetime import timedelta
delta_1 = timedelta(days=40)
delta_2 = timedelta(minutes=5, hours=28, weeks=2)
delta_3 = timedelta(hours=28, seconds=5, microseconds=10, milliseconds=39000)
print(delta_1, type(delta_1))
# 40 days, 0:00:00 <class 'datetime.timedelta'>
print(delta_2, type(delta_2))
# 15 days, 4:05:00 <class 'datetime.timedelta'>
print(delta_3, type(delta_3)) # 1 day, 4:00:44.000010 <class 'datetime.timedelta'>
Присмотритесь внимательно к параметрам, которые были переданы объектам, и что выводит в результате объект timedelta
. Все это из-за процесса нормализации данных и особенностей хранения информации внутри timedelta
.
Экземпляр datetime.timedelta
хранит все переданные данные только в виде сочетания days
, seconds
и microseconds
, а остальные переданные аргументы инициализации конвертируются в эти единицы следующим образом:
week
преобразуется в 7 days
hour
преобразуется в 3600 seconds
.
minute
преобразуется в 60 seconds
.
millisecond
преобразуется в 1000 microseconds
.
Например, timedelta(seconds=90000) можно представить как timedelta(days=1, seconds=3600). Это происходит потому, что
1 день = 24 часа * 60 минут * 60 секунд = 86400 секунд
86400 секунды + 3600 секунд = 90000 секунд
Давайте рассмотрим как произойдет нормализация на примере значения timedelta(minutes=5, hours=28, weeks=2)
Вспоминаем, что timedelta хранит все в виде дней, секунд и микросекунд. У значения timedelta(minutes=5, hours=28, weeks=2)
микросекунды отсутствуют, значит остается посчитать дни и секунды. Поехали:
5 минут = 5*60 секунд = 300 секунд
28 часов = 1 день и 4 часа = 1 день и 4*60 минут*60 секунд = 1 день и 14400 секунд
2 недели = 14 дней
В итоге суммируем
14 дней + 1 день и 14400 секунд + 300 секунд = 15 дней 14700 секунд
Проверяем в консоли
>>> from datetime import timedelta
>>> timedelta(minutes=5, hours=28, weeks=2)
datetime.timedelta(days=15, seconds=14700)
Все сходится. Все переданные параметры нормализуются в days
, seconds
и microseconds
так, чтобы значения в этих атрибутах соответствовали значениям в таблице:
Атрибуты | Минимальное и максимальное возможные значения |
---|---|
days | Между -999999999 и 999999999 |
seconds | Между 0 to 86399 (3600*24 количество секунд в одном дне) |
microseconds | Между 0 и 999999 |
Если нормализованное значение дней выйдет за пределы диапазона -999999999 <= days <= 999999999, то возникнет исключение OverflowError
.
С объектом timedelta можно выполнять несколько математических операций, при этом он может вступать во взаимодействие как с числами, так и с другими объектами timedelta. Давайте разберем эти случаи.
Объект также можно создать или правильнее в данном случае сказать получить, если вычесть из одной даты другую:
from datetime import datetime, date
current_dt = datetime.now()
my_dt = datetime(year=2023, month=3, day=21, hour=12, minute=30)
diff = current_dt - my_dt
print(diff, type(diff)) # 581 days, 5:30:14.610868 <class 'datetime.timedelta'>
При вычитании нужно использовать одинаковые типы: из типа date
можно вычитать тип date
. Если вычитаете из типа datetime
, то только такой же объект datetime
. Иначе получите ошибку TypeError: unsupported operand type(s) for -: 'datetime.date' and 'datetime.datetime'.
Между собой два объекта timedelta
могут складываться и вычитаться. В результате будет получаться новый объект timedelta
from datetime import timedelta
delta1 = timedelta(days=2, hours=12)
delta2 = timedelta(hours=18, minutes=30)
sum_td = delta1 + delta2
print(sum_td)
# 3 days, 6:30:00
diff_1 = delta2 - delta1
print(diff_1)
# -2 days, 6:30:00
diff_2 = delta1 - delta2
print(diff_2) # 1 day, 17:30:00
Два объекта timedelta
могут поучаствовать в операциях деления ( /, //, %)
from datetime import timedelta
delta1 = timedelta(days=2, hours=12)
delta2 = timedelta(hours=18, minutes=30)
print(delta1 / delta2)
# 3.2432432432432434
print(delta2 / delta1)
# 0.30833333333333335
print('-----')
print(delta1 // delta2)
# 3
print(delta2 // delta1)
# 0
print('-----')
print(delta1 % delta2)
# 4:30:00
print(delta2 % delta1)
# 18:30:00
Во время деления вместо объектов timedelta
подставляется общее количество секунд, содержащихся в каждом объекте. Поэтому будут эквиваленты строка
delta1 / delta2
и строка
delta1.total_seconds() / delta2.total_seconds()
При деление delta1 / delta2 возвращается вещественное число, при delta1 // delta2 результатом будет целое число, остаток при этом отбрасывается.
Самое интересное происходит при операции delta1 % delta2. Здесь вычисляется остаток от деления количества секунд первого объекта на второй. И затем результат представляется в виде объекта timedelta
.
Вы можете к объектам date/datetime прибавлять или вычитать объект timedelta. В результате у вас будет получаться новый объект date/datetime, увеличенный или уменьшенный на временную разницу, хранящуюся в timedelta
from datetime import timedelta, datetime, date
delta1 = timedelta(days=3)
my_date = date(2023, 8, 21)
new_date = my_date + delta1
print(new_date, type(new_date))
# 2023-08-24 <class 'datetime.date'>
print(my_date - delta1)
#
print()
delta2 = timedelta(hours=18, minutes=30)
my_datetime = datetime(2023, 9, 10, 15, 0)
new_datetime = my_datetime + delta2
print(new_datetime, type(new_datetime))
# 2023-09-11 09:30:00 <class 'datetime.datetime'>
print(my_datetime - delta2) # 2023-09-09 20:30:00
Объект timedelta можно умножать на число или делить на число. При делении можно использовать только оператор обычного деления /
и целочисленного //
.
from datetime import timedelta
delta = timedelta(hours=4, minutes=15)
multiplier = 3
result = delta * multiplier
print(result)
# 12:45:00
print(delta / 4)
# 1:03:45
print(delta // 4) # 1:03:45
Из оставшихся нерассмотренных операций можно выделить следующие:
Операция | Результат операции |
---|---|
-td | Эквивалентно datetime.timedelta(-t1.days, -t1.seconds, -t1.microseconds) и так же t1 * -1. |
abs(td) | Эквивалентно '+t', когда t.days >= 0, и '-t', когда t.days < 0. |
str(td) | Возвращает строку в форме [D day [s],] [H] H: MM: SS [.UUUUUU], где D отрицательно для отрицательного 't'. |
repr(td) | Возвращает строковое представление объекта 'datetime.timedelta' в виде вызова конструктора со значениями канонического атрибута. |