Объект timedelta модуля datetime

 timedelta — это класс из модуля datetime в Python, предназначенный для представления разницы между двумя датами или временем. Он позволяет удобно выполнять операции с датами, такие как сложение или вычитание временных интервалов. Основные параметры, с которыми работает timedelta, включают дни, часы, минуты, секунды и микросекунды.

Создание объекта timedelta возможно с использованием различных аргументов. Например, timedelta(days=5) создаст интервал в пять дней, а timedelta(hours=2, minutes=30) — интервал длиной в два часа и тридцать минут.

Данный класс поддерживает арифметические операции, что позволяет легко манипулировать датами. Можно прибавить интервал к объекту datetime, используя оператор +, или вычесть, используя оператор -. В результате, timedelta делает работу с датами более интуитивной и эффективной. Кроме того, через методы total_seconds() и другие, возможно извлечь детальные данные о временном промежутке, что значительно облегчает разработку временноориентированных приложений.

Создание объекта timedelta

Импортируйте класс из модуля 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 хранит все переданные данные только в виде сочетания daysseconds и 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)

Все сходится. Все переданные параметры нормализуются в daysseconds и microseconds  так, чтобы значения в этих атрибутах соответствовали значениям в таблице:

АтрибутыМинимальное и максимальное возможные значения
daysМежду -999999999 и 999999999
secondsМежду 0 to 86399 (3600*24 количество секунд в одном дне)
microsecondsМежду 0 и 999999

Если нормализованное значение дней выйдет за пределы диапазона -999999999 <= days <= 999999999, то возникнет исключение OverflowError.

Операции с объектом timedelta

С объектом timedelta можно выполнять несколько математических операций, при этом он может вступать во взаимодействие как с числами, так и с другими  объектами timedelta. Давайте разберем эти случаи.

Разница двух времен в Python

Объект также можно создать или правильнее в данном случае сказать получить, если вычесть из одной даты другую:

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

Между собой два объекта 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.

Операции между объектами timedelta и date/datetime

Вы можете к объектам  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 с числами

Объект 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

Остальные операции с timedelta

Из оставшихся нерассмотренных операций можно выделить следующие:

Операция Результат операции
-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' в виде вызова конструктора со значениями канонического атрибута.

Перейти к следующему шагу

Комментарии