Converting datetime objects to seconds is a task that serves two distinct purposes in Python: obtaining Unix timestamps for storage, APIs, and inter-system communication, or calculating durations between two points in time. Each purpose requires a different approach, and mixing them up is a common source of bugs.
In this guide, you will learn how to convert datetime objects and durations to seconds using Python's built-in modules, avoid critical pitfalls like the .seconds vs .total_seconds() trap, and handle timezones correctly.
Understanding Unix Timestamps (Epoch Time)
A Unix timestamp represents the number of seconds that have elapsed since January 1, 1970, 00:00:00 UTC, commonly referred to as the Unix epoch. This is the standard way to represent a specific moment in time as a single number.
Getting the Current Timestamp
from datetime import datetime, timezone
now_utc = datetime.now(timezone.utc)
timestamp = now_utc.timestamp()
print(f"Datetime: {now_utc}")
print(f"Unix timestamp: {timestamp}")
print(f"As integer: {int(timestamp)}")Output (values will vary based on the current time):
Datetime: 2026-02-13 10:26:28.489621+00:00
Unix timestamp: 1770978388.489621
As integer: 1770978388Converting a Specific Datetime to a Timestamp
from datetime import datetime, timezone
dt = datetime(2026, 12, 31, 23, 59, 59, tzinfo=timezone.utc)
timestamp = dt.timestamp()
print(f"Datetime: {dt}")
print(f"Timestamp: {timestamp}")Output:
Datetime: 2026-12-31 23:59:59+00:00
Timestamp: 1798761599.0Converting Durations with timedelta
The timedelta object represents a span of time rather than a specific moment. Its .total_seconds() method converts the entire duration into seconds.
from datetime import timedelta
duration = timedelta(hours=2, minutes=30, seconds=45)
total_seconds = duration.total_seconds()
print(f"Duration: {duration}")
print(f"Total seconds: {total_seconds}")Output:
Duration: 2:30:45
Total seconds: 9045.0Calculating the Difference Between Two Datetimes
Subtracting one datetime from another produces a timedelta, which you can then convert to seconds:
from datetime import datetime
start = datetime(2023, 1, 1, 9, 0, 0)
end = datetime(2023, 1, 1, 17, 30, 0)
difference = end - start
seconds_elapsed = difference.total_seconds()
print(f"Duration: {difference}")
print(f"In seconds: {seconds_elapsed}")
print(f"In minutes: {seconds_elapsed / 60}")
print(f"In hours: {seconds_elapsed / 3600}")Output:
Duration: 8:30:00
In seconds: 30600.0
In minutes: 510.0
In hours: 8.5The .seconds vs .total_seconds() Trap
This is one of the most common and dangerous pitfalls when working with durations in Python. The .seconds attribute and the .total_seconds() method look similar but behave very differently.
Incorrect approach (.seconds ignores the days component):
from datetime import timedelta
duration = timedelta(days=2, hours=5, minutes=30)
print(f".seconds: {duration.seconds}")Output:
.seconds: 19800The value 19800 represents only 5 hours and 30 minutes (the time portion), completely ignoring the 2 days.
Correct approach (.total_seconds() includes the full duration):
from datetime import timedelta
duration = timedelta(days=2, hours=5, minutes=30)
print(f".total_seconds(): {duration.total_seconds()}")Output:
.total_seconds(): 192600.0The value 192600.0 correctly accounts for 2 full days (172800 seconds) plus 5 hours and 30 minutes (19800 seconds).
Converting Time Components to Seconds Manually
Sometimes you need to convert individual hours, minutes, and seconds values into a total number of seconds without creating datetime objects.
def time_to_seconds(hours=0, minutes=0, seconds=0):
"""Convert time components to total seconds."""
return hours * 3600 + minutes * 60 + seconds
total = time_to_seconds(hours=2, minutes=45, seconds=30)
print(f"2h 45m 30s = {total} seconds")Output:
2h 45m 30s = 9930 secondsConverting a time Object to Seconds Since Midnight
The datetime.time object does not have a .total_seconds() method, so you need to compute it from its components:
from datetime import time
t = time(14, 30, 45) # 2:30:45 PM
seconds_since_midnight = t.hour * 3600 + t.minute * 60 + t.second
print(f"{t} is {seconds_since_midnight} seconds since midnight")Output:
14:30:45 is 52245 seconds since midnightConverting Seconds Back to a Readable Format
When you have a large number of seconds and need to display it in a human-friendly way, use divmod() to break it down:
def seconds_to_readable(seconds):
"""Convert seconds to a human-readable duration string."""
days, remainder = divmod(int(seconds), 86400)
hours, remainder = divmod(remainder, 3600)
minutes, secs = divmod(remainder, 60)
parts = []
if days:
parts.append(f"{days}d")
if hours:
parts.append(f"{hours}h")
if minutes:
parts.append(f"{minutes}m")
if secs or not parts:
parts.append(f"{secs}s")
return " ".join(parts)
print(seconds_to_readable(90061))
print(seconds_to_readable(3665))
print(seconds_to_readable(45))
print(seconds_to_readable(0))Output:
1d 1h 1m 1s
1h 1m 5s
45s
0sWorking with Milliseconds and Microseconds
Some APIs and systems use milliseconds (common in JavaScript and Java) or microseconds instead of seconds:
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
timestamp_sec = now.timestamp()
timestamp_ms = int(now.timestamp() * 1000)
timestamp_us = int(now.timestamp() * 1_000_000)
print(f"Seconds: {timestamp_sec}")
print(f"Milliseconds: {timestamp_ms}")
print(f"Microseconds: {timestamp_us}")Output (values will vary):
Seconds: 1770978630.356482
Milliseconds: 1770978630356
Microseconds: 1770978630356482Measuring Elapsed Time for Performance
When measuring how long a piece of code takes to execute, avoid using datetime.now(). Instead, use time.perf_counter(), which provides the highest available resolution and is not affected by system clock adjustments:
import time
start = time.perf_counter()
time.sleep(1.5)
end = time.perf_counter()
elapsed = end - start
print(f"Elapsed: {elapsed:.4f} seconds")Output:
Elapsed: 1.5001 secondsTimezone-Aware Conversions
Understanding how timezones affect timestamp conversions is essential for writing correct code in applications that span multiple regions:
from datetime import datetime, timezone
from zoneinfo import ZoneInfo # Python 3.9+
dt_utc = datetime(2023, 6, 15, 12, 0, 0, tzinfo=timezone.utc)
dt_ny = datetime(2023, 6, 15, 12, 0, 0, tzinfo=ZoneInfo("America/New_York"))
print(f"UTC noon timestamp: {dt_utc.timestamp()}")
print(f"NYC noon timestamp: {dt_ny.timestamp()}")
diff = dt_ny.timestamp() - dt_utc.timestamp()
print(f"Offset: {diff / 3600} hours")Output:
UTC noon timestamp: 1686830400.0
NYC noon timestamp: 1686844800.0
Offset: 4.0 hoursNYC noon happens 4 hours after UTC noon during Eastern Daylight Time, which is why its timestamp is larger.
Method Reference
| Goal | Method | Returns |
|---|---|---|
| Datetime to Unix epoch | dt.timestamp() |
float (seconds since epoch) |
| Full duration to seconds | td.total_seconds() |
float (total seconds) |
| Seconds component only | td.seconds |
int (0 to 86399, partial) |
| High-precision elapsed time | time.perf_counter() |
float (seconds) |
| Monotonic clock for scheduling | time.monotonic() |
float (seconds) |
Conclusion
Converting datetime values to seconds in Python is straightforward once you understand the distinction between timestamps (specific moments in time) and durations (spans of time). Use datetime.timestamp() to get Unix epoch seconds, and use timedelta.total_seconds() to convert durations. Always prefer .total_seconds() over .seconds to avoid silently dropping the days component from your calculations, and always attach explicit timezone information to your datetime objects to ensure consistent behavior across different environments.
For performance measurement, reach for time.perf_counter() instead of datetime subtraction, as it provides higher resolution and immunity to system clock changes.