Python
datetime
time difference
programming
coding tips

How do I find the time difference between two datetime objects in python?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Finding the difference between two datetime values in Python looks simple, but correctness depends on input quality and timezone handling. A direct subtraction gives a timedelta, which is perfect for machine calculations. In production code, the bigger challenge is deciding how to normalize timestamps before subtraction so results remain stable across regions and daylight saving boundaries.

Core Sections

Subtracting datetime objects directly

The baseline operation is subtraction. If both values are naive or both are aware with compatible timezone information, Python returns a timedelta.

python
1from datetime import datetime
2
3start = datetime(2026, 3, 4, 9, 15, 0)
4end = datetime(2026, 3, 4, 12, 5, 45)
5
6delta = end - start
7print(delta)                 # 2:50:45
8print(delta.days)            # 0
9print(delta.seconds)         # 10245
10print(delta.total_seconds()) # 10245.0

Use total_seconds for calculations. The seconds field only represents the non-day remainder and often causes subtle bugs when durations cross midnight or span multiple days.

Handling aware datetimes and timezone normalization

If timestamps come from APIs, databases, or logs, they are often timezone-aware. Normalize both values to the same timezone before subtraction to avoid ambiguity. UTC is usually the safest internal representation.

python
1from datetime import datetime
2from zoneinfo import ZoneInfo
3
4toronto = ZoneInfo('America/Toronto')
5utc = ZoneInfo('UTC')
6
7start_local = datetime(2026, 11, 1, 1, 30, tzinfo=toronto)
8end_utc = datetime(2026, 11, 1, 7, 15, tzinfo=utc)
9
10delta = end_utc.astimezone(utc) - start_local.astimezone(utc)
11print(delta)
12print(delta.total_seconds())

The key point is consistency. Subtraction between aware values is reliable when both are compared on the same offset basis. Without explicit normalization, daylight-saving transitions can confuse both humans and reviewers, even when Python handles the arithmetic correctly.

Turning timedelta into useful output

Users rarely want raw seconds. They need readable hours, minutes, and seconds. A small formatter keeps presentation logic separate from arithmetic logic.

python
1from datetime import timedelta
2
3def format_duration(delta: timedelta) -> str:
4    total = int(delta.total_seconds())
5    sign = '-' if total < 0 else ''
6    total = abs(total)
7
8    hours, rem = divmod(total, 3600)
9    minutes, seconds = divmod(rem, 60)
10    return f"{sign}{hours}h {minutes}m {seconds}s"
11
12print(format_duration(timedelta(seconds=3661)))
13print(format_duration(timedelta(seconds=-95)))

Keeping formatting in a dedicated function makes testing straightforward. You can test multiple edge cases such as negative intervals or multi-day durations without touching data access code.

A reusable helper for API and database inputs

Many codebases receive timestamps as ISO strings. The helper below parses input, enforces timezone awareness, and returns seconds. This pattern gives one predictable behavior for the whole application.

python
1from datetime import datetime
2from zoneinfo import ZoneInfo
3
4def diff_seconds(start_iso: str, end_iso: str, assume_tz: str = 'UTC') -> float:
5    tz = ZoneInfo(assume_tz)
6
7    start = datetime.fromisoformat(start_iso)
8    end = datetime.fromisoformat(end_iso)
9
10    if start.tzinfo is None:
11        start = start.replace(tzinfo=tz)
12    if end.tzinfo is None:
13        end = end.replace(tzinfo=tz)
14
15    start_utc = start.astimezone(ZoneInfo('UTC'))
16    end_utc = end.astimezone(ZoneInfo('UTC'))
17    return (end_utc - start_utc).total_seconds()
18
19print(diff_seconds('2026-03-04T10:00:00', '2026-03-04T10:05:30'))
20print(diff_seconds('2026-03-04T10:00:00-05:00', '2026-03-04T15:10:00+00:00'))

In review discussions, this style is easier to reason about because assumptions are explicit. Every caller can see whether naive inputs are accepted and which timezone default applies.

Common Pitfalls

  • Mixing naive and aware datetime values in the same subtraction.
  • Using delta.seconds when you actually need delta.total_seconds.
  • Formatting durations inline in many call sites instead of using one helper.
  • Ignoring negative durations when event order can be reversed.
  • Relying on local machine timezone instead of a documented normalization policy.

Summary

  • Subtracting two datetime values returns a timedelta.
  • Use total_seconds for reliable arithmetic and storage.
  • Normalize timezone-aware values to a common zone, usually UTC.
  • Keep parsing, arithmetic, and formatting concerns in separate functions.
  • Add tests for multi-day, negative, and timezone transition scenarios.

Course illustration
Course illustration

All Rights Reserved.