Time Travel in Python: Adding and Subtracting Time with timedelta
Adding and subtracting time is one of the most common operations in data science — calculating days since last purchase, projecting future dates, creating rolling windows, or measuring freshness of data. Python’s timedelta class from the datetime module makes “time travel” simple, precise, and readable.
TL;DR — Core timedelta Usage
timedelta(days=..., hours=..., minutes=...)- Use
+and-withdatetimeobjects - Works seamlessly with pandas
.dtaccessor - Always work with timezone-aware datetimes in 2026
1. Basic Time Travel Operations
from datetime import datetime, timedelta
from zoneinfo import ZoneInfo
now_utc = datetime.now(ZoneInfo("UTC"))
# Add time
future = now_utc + timedelta(days=30, hours=6, minutes=45)
print("30 days and 6h45m from now:", future)
# Subtract time
past = now_utc - timedelta(weeks=2, days=3)
print("2 weeks and 3 days ago:", past)
2. Real-World Data Science Examples
import pandas as pd
# Small inline sample so this example runs as-is.
# In a real project you would load it with pd.read_csv("sales_data.csv")
df = pd.DataFrame({
"customer_id": [101, 102, 103, 104, 105, 106],
"customer_name": ["Ana", "Ben", "Chen", "Dana", "Eli", "Fay"],
"order_date": ["2026-01-05", "2026-01-12", "2026-02-03",
"2026-02-18", "2026-03-01", "2026-03-09"],
"amount": [1250.75, 890.50, 2340.00, 1780.25, 2615.40, 450.00],
"quantity": [3, 2, 5, 4, 6, 1],
"profit": [312.69, 222.63, 585.00, 445.06, 653.85, 112.50],
"region": ["North", "South", "East", "North", "West", "South"],
"category": ["Electronics", "Books", "Electronics", "Home", "Home", "Books"],
"rating": [5, 4, None, 3, 5, 4],
"year": [2025, 2025, 2026, 2026, 2026, 2026],
"description": ["fast laptop", "python book", "noise cancelling headphones",
"desk lamp", "standing desk", "data science book"],
})
df["order_date"] = pd.to_datetime(df["order_date"]).dt.tz_localize("UTC") # make the dates UTC-aware
# Current time for freshness analysis
current_utc = datetime.now(ZoneInfo("UTC"))
# Calculate time differences
df["hours_since_order"] = (current_utc - df["order_date"]).dt.total_seconds() / 3600
df["days_since_order"] = (current_utc - df["order_date"]).dt.days
# Future projection
df["projected_delivery"] = df["order_date"] + timedelta(days=14)
# Rolling window example
df["sales_7_days_ago"] = df["amount"] - (df["amount"].shift(7) if "amount" in df else 0)
3. Advanced timedelta Techniques
# Relative time calculations
one_month_ago = now_utc - timedelta(days=30) # approximate
from dateutil.relativedelta import relativedelta # installed with pandas
exact_one_month_ago = now_utc - relativedelta(months=1) # calendar month, handles day 31
# Business day calculations (simple example)
# timedelta(days=5) is 5 calendar days; for business days use pandas offsets
five_business_days = pd.Timestamp("2026-03-19") + pd.offsets.BDay(5)
print(five_business_days.date()) # 2026-03-26
4. Best Practices in 2026
- Always use timezone-aware datetimes with
ZoneInfo - Prefer
timedeltaover manual arithmetic for clarity and accuracy - Use pandas
.dtaccessor for vectorized time calculations on DataFrames - Store original timestamps and derived time features separately
- Consider
dateutil.relativedeltafor complex calendar arithmetic (months/years)
What timedelta Can and Cannot Represent
A timedelta stores an exact duration in days, seconds and microseconds. Weeks, hours and minutes are converted into those units, so they are exact too. Months and years are deliberately missing because they have no fixed length: "one month after 31 January" has no single answer. For calendar arithmetic use dateutil.relativedelta or pandas DateOffset, and for business days use pd.offsets.BDay or numpy.busday_offset.
Worked Example: Durations as Numbers
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
start = datetime(2026, 1, 31, 8, 0)
end = datetime(2026, 3, 2, 20, 30)
gap = end - start
print(gap) # 30 days, 12:30:00
print(gap.days, gap.seconds) # 30 45000 (seconds part only!)
print(gap.total_seconds() / 3600) # 732.5 hours
print(gap / timedelta(days=1)) # 30.520833333333332 days
print(gap // timedelta(weeks=1), "full weeks")
print(start + relativedelta(months=1)) # 2026-02-28 08:00:00 (clamped)
print(start + timedelta(days=30)) # 2026-03-02 08:00:00
print(-timedelta(hours=1)) # -1 day, 23:00:00
Two details often surprise people: .seconds is only the leftover part below one day, and negative durations are normalised to negative days plus positive seconds.
Common Mistakes
- Using
.secondsas a total: usetotal_seconds() - Treating 30 days as a month in billing or reporting logic
- Subtracting naive dates from an aware "now": localise them first
Quick Summary
timedeltafor exact durations,relativedeltafor calendar steps- Divide by
timedelta(...)to get numeric durations - Use business-day offsets when weekends must be skipped
Conclusion
Time travel in Python with timedelta is simple yet incredibly powerful for data science. In 2026, combining timedelta with timezone-aware datetime objects and pandas .dt accessor lets you perform freshness checks, rolling calculations, projections, and feature engineering with clean, readable, and accurate code.
Next steps:
- Open one of your datasets with datetime columns and add useful time-delta features using the patterns above