Сообщить об ошибке.

Приемы работы с datetime.timedelta()

В этом разделе представлены частые приемы работы длительностью или интервалом времени datetime.timedelta(), а так же арифметика c datetime.timedelta.

Содержание:


Примеры арифметики c datetime.timedelta():

>>> from datetime import timedelta
>>> year = timedelta(days=365)
>>> ten_years = 10 * year
>>> ten_years
# datetime.timedelta(days=3650)
>>> ten_years.days
# 3650
>>> ten_years.days // 365
# 10
>>> nine_years = ten_years - year
>>> nine_years
# datetime.timedelta(days=3285)
>>> three_years = nine_years // 3
>>> three_years, three_years.days // 365
# (datetime.timedelta(days=1095), 3)

Преобразование интервала datetime.timedelta() в секунды:

>>> import datetime
>>> delta = datetime.timedelta(minutes=1)
>>> delta.total_seconds()
# 60.0
>>> delta = datetime.timedelta(hours=1, minutes=1)
>>> delta.total_seconds()
# 3660.0
>>> delta = datetime.timedelta(days=1, hours=1, minutes=1)
>>> delta.total_seconds()
# 90060.0
>>> delta = datetime.timedelta(weeks=3, days=5)
>>> delta.total_seconds()
# 2246400.0

# Интервал между датами
>>> date1 = datetime.datetime.now()
>>> date2 = datetime.datetime(2021, 1, 1) 
>>> delta = date2 - date1
>>> delta.total_seconds()
# 20662333.983181

Форматирование вывода интервала времени datetime.timedelta().

Для объектов datetime.timedelta нет встроенного средства форматирования, но это довольно легко сделать самостоятельно:

import datetime

def timedelta_to_hms(duration):
    # преобразование в часы, минуты и секунды
    days, seconds = duration.days, duration.seconds
    hours = days * 24 + seconds // 3600
    minutes = (seconds % 3600) // 60
    seconds = (seconds % 60)
    return hours, minutes, seconds

def timedelta_to_dhms(duration):
    # преобразование в дни, часы, минуты и секунды
    days, seconds = duration.days, duration.seconds
    hours = seconds // 3600
    minutes = (seconds % 3600) // 60
    seconds = (seconds % 60)
    return days, hours, minutes, seconds

Узнаем сколько прошло времени с события.

# узнаем сколько прошло с 13 января до сегодня
>>> td = datetime.datetime.now() - datetime.datetime(2020, 1, 13)
>>> days, hours, minutes, seconds = timedelta_to_dhms(td)
>>> print(f'{days} days, {hours} hours, {minutes} minutes')
# 112 days, 18 hours, 16 minutes

Узнаем сколько осталось времени до события.

# узнаем сколько часов осталось до 1 июня
>>> td = datetime.datetime(2020, 6, 1) - datetime.datetime.now()
>>> hours, minutes, seconds = timedelta_to_hms(td)
>>> print(f'{hours} hours, {minutes} minutes')
# 653 hours, 39 minutes

Пример подсчета дней до события.

При помощи datetime.datetime.

>>> import datetime
>>> today = datetime.datetime.now()
>>> date = datetime.datetime(2020, 7, 14)
>>> delta = date - today
>>> delta.days
# 69

# функция `timedelta_to_dhms()` создана выше 
# в подразделе Форматирование вывода
>>> days, hours, minutes, _ = timedelta_to_dhms(delta)
>>> print(f'{days} days, {hours} hours, {minutes} minutes')
69 days, 10 hours, 46 minutes

При помощи datetime.date.

>>> import datetime
>>> today = datetime.date.today()
>>> date = datetime.date(today.year, 7, 14)
>>> delta = date - today
>>> delta.days
# 70

# функция `timedelta_to_dhms()` создана выше 
# в подразделе Форматирование вывода
>>> days, hours, minutes, _ = timedelta_to_dhms(delta)
>>> print(f'{days} days, {hours} hours, {minutes} minutes')
69 days, 0 hours, 0 minutes

Подсчет прошедших и предстоящих дат.

Узнаем дату "дня программиста". Как известно, день программиста приходится на 256 день в году.

>>> import datetime
# текущая дата, из который нужно вытащить год
today = datetime.date.today()
# дата начала года 
>>> first_day_year = datetime.date(today.year, 1, 1)
# разница в 256 дней
>>> delta = datetime.timedelta(days=256)
>>> prog_day = first_day_year + delta
>>> print(f'{prog_day.day}.{prog_day.month}.{prog_day.year}')
# 14.9.2022

Узнаем, какая дата будет через 3 недели и 5 дней.

>>> import datetime
>>> today = datetime.datetime.now()
>>> today
# datetime.datetime(2020, 5, 6, 20, 10, 5, 57219)
>>> print(f'{today.day}.{today.month}.{today.year}')
# 6.5.2020
>>> delta = datetime.timedelta(weeks=3, days=5)
>>> date = today + delta
>>> date
# datetime.datetime(2020, 6, 1, 20, 10, 5, 57219)
>>> print(f'{date.day}.{date.month}.{date.year}')
# 1.6.2020

Узнаем, какая дата была 100 дней назад.

>>> import datetime
>>> today = datetime.datetime.now()
>>> today
# datetime.datetime(2020, 5, 6, 20, 10, 34, 792857)
>>> print(f'{today.day}.{today.month}.{today.year}')
# 6.5.2020
>>> delta = datetime.timedelta(days=100)
>>> date = today - delta
>>> date
# datetime.datetime(2020, 1, 27, 20, 10, 34, 792857)
>>> print(f'{date.day}.{date.month}.{date.year}')
# 27.1.2020

Узнаем, какое время будет через 1 час 30 минут и 45 секунд.

>>> import datetime
>>> today = datetime.datetime.now()
>>> today
# datetime.datetime(2020, 5, 6, 20, 11, 2, 522895)
>>> print(f'{today.hour}:{today.minute}:{today.second}')
# 20:11:2
>>> delta = datetime.timedelta(hours=1, minutes=30, seconds=45)
>>> date = today + delta
>>> date
# datetime.datetime(2020, 5, 6, 21, 41, 47, 522895)
>>> print(f'{date.hour}:{date.minute}:{date.second}')
# 21:41:47

Использование месяца, при расчете интервала timedelta.

В конструкторе объекта datetime.timedelta() нет аргумента, отвечающего за месяц, следовательно его надо рассчитывать. Как тогда точно рассчитать количество дней в нескольких месяцах, если количество дней в месяцах разное? А если расчеты выпадут на февраль и да еще год високосный?

Для подсчета дней в месяцах можно воспользоваться функцией calendar.monthrange() встроенного модуля calendar. Рассчитаем дату, которая будет через 3 месяца и 6 дней от текущей:

import datetime, calendar, locale
# переменные для расчета даты 
# через 3 месяца и 6 дней
month = 3
day = 6
# текущая дата 
today = datetime.date.today()
# расчет количества дней в 3-х месяцах
sum_mont = 0
for i in range(today.month, today.month+month):
    _, month_days = calendar.monthrange(today.year, i)
    sum_mont += month_days
# количество дней до назначенной даты
total_days = sum_mont + day
# рассчитываем дельту
delta = datetime.timedelta(days=total_days)
# вычисляем дату
deadline = today + delta
print(f'{deadline.day}.{deadline.month}.{deadline.year}')
# номер дня недели (0-понедельник)
n_weekday = calendar.weekday(deadline.year, deadline.month, deadline.day)
print(f'Номер дня недели => {n_weekday}')
#выбираем русскую локаль, если нужны 
# названия дней недели в кириллице
locale.setlocale(locale.LC_ALL, 'ru_RU.UTF-8')
# название дня недели
day_name = calendar.day_name[n_weekday]
print(f'Название дня недели => {day_name}')
# сокращенное название дня недели
day_abbr = calendar.day_abbr[n_weekday]
print(f'Сокращенное название дня недели => {day_abbr}')

# 17.5.2022
# Номер дня недели => 1
# Название дня недели => Вторник
# Сокращенное название дня недели => Вт

Создание диапазона дат в Python

>>> import datetime
>>> base = datetime.date.today()
>>> numday = 10
>>> date_list = [base + datetime.timedelta(days=x) for x in range(numdays)]
>>> date_list
# [
#     datetime.date(2024, 1, 25), datetime.date(2024, 1, 26), 
#     datetime.date(2024, 1, 27), datetime.date(2024, 1, 28), 
#     datetime.date(2024, 1, 29), datetime.date(2024, 1, 30), 
#     datetime.date(2024, 1, 31), datetime.date(2024, 2, 1), 
#     datetime.date(2024, 2, 2), datetime.date(2024, 2, 3)
# ]

>>> for d in date_list:
...   str(d)

# '2024-01-25'
# '2024-01-26'
# '2024-01-27'
# '2024-01-28'
# '2024-01-29'
# '2024-01-30'
# '2024-01-31'
# '2024-02-01'
# '2024-02-02'
# '2024-02-03'