runtime
103 / 250
lesson 103 Dates Numbers & Regex · intermediate

Durations with timedelta

Subtracting two datetimes gives a timedelta: how long something took. Adding a timedelta to a date moves it. `total_seconds()` is the whole duration; `.seconds` is only part of it.

You'll be able to
  • Subtract two datetimes and read the result's days and total_seconds()
  • Add or subtract timedelta(days=…, hours=…) to move a date
  • Avoid .seconds, which ignores whole days, and compare dates with dates
The idea

How long did delivery take? Is this order late? When is the payment due? All three are durations. Subtracting one datetime from another gives a timedelta, and a timedelta can be added to a datetime to move it: ordered + timedelta(days=6).

A timedelta stores days, seconds and microseconds. delta.days is the whole days, delta.total_seconds() is the entire duration in seconds (a float), and dividing gives other units: delta.total_seconds() / 3600 is hours.

Run each example to see what it prints. Running examples doesn't count toward progress.

example-1.py · How long delivery took
from datetime import datetime, timedelta

ordered = datetime.fromisoformat("2024-01-03 18:35:10")
delivered = datetime.fromisoformat("2024-01-07 11:00:39")
wait = delivered - ordered
print(wait)
print(wait.days, wait.seconds, wait.total_seconds())
print(ordered + timedelta(days=6))

Dates and datetimes are different types. date (a calendar day, no time) comes from datetime.date() or date.fromisoformat("2024-01-09"). Subtracting one from the other isn't allowed, so convert first.

example-2.py · A date minus a datetime
from datetime import date, datetime

due = date.fromisoformat("2024-01-09")
delivered = datetime.fromisoformat("2024-01-07 11:00:39")
print(due - delivered)
example-3.py · Days late, compared by calendar day
from datetime import date, datetime

def days_late(delivered_at, estimated):
    delivered = datetime.fromisoformat(delivered_at).date()
    due = date.fromisoformat(estimated)
    late = (delivered - due).days
    if late < 0:
        return 0
    return late

print(days_late("2024-01-07 11:00:39", "2024-01-09"))
print(days_late("2024-12-28 04:12:39", "2024-12-27"))
print(days_late("2024-12-27 23:59:00", "2024-12-27"))

When to use it: delivery and response times, due dates, "in the last 7 days" filters, SLAs. Mistakes to avoid: reading .seconds as the total (it resets every day), mixing date and datetime, and comparing a duration with a plain number: write wait > timedelta(hours=24), not wait > 24.

Review
  • later - earlier is a timedelta; datetime + timedelta(...) moves a date.
  • total_seconds() is the whole duration; .days is whole days only and .seconds is just the remainder.
  • Compare durations with timedeltas, and calendar days with date() values.
  • Next: amounts of money that add up exactly, with Decimal.
Practise this

Loading your progress…

To master this lesson, solve both challenges without hints or the answer, and pass the concept check.

Durations with timedelta — Dates Numbers & Regex · Runtime