datetime.timestamp
For an aware datetime it is exact arithmetic: (dt - epoch) / 1 second. For a naive one Python asks the operating system what that local time was — so the same naive value gives different timestamps on different machines.
Common call
datetime(2026, 9, 29, 12, tzinfo=UTC).timestamp()
Returns
1790683200.0
Replaces
calendar.timegm(dt.utctimetuple()) and time.mktime(dt.timetuple())
Watch out
Naive values are interpreted as LOCAL time
dt.timestamp()
→ float
Demo
Live evaluation
Aware input gives the same answer everywhere. Naive input is flagged rather than guessed, because the real answer depends on the machine.
Try:
Inputs
whenstran ISO 8601 timestamp
Code
from datetime import datetime dt = datetime.fromisoformat('2026-09-29T12:00Z') dt.timestamp() if dt.tzinfo else 'naive: timestamp() would use local time'
Result
1790683200.0
12:00Z and 14:00+02:00 are the same instant, so both give 1790683200.0. Microseconds become the fractional part. A naive value has no offset, and CPython would call the C library's mktime() with the machine's timezone — the demo refuses to guess.
Common patterns
Integer seconds
int() truncates toward zero; fine for positive timestamps.
epoch = int(dt.timestamp())
Milliseconds for JavaScript
Exact integer milliseconds without float rounding.
from datetime import datetime, timedelta, UTC ms = (dt - datetime(1970, 1, 1, tzinfo=UTC)) // timedelta(milliseconds=1)
Naive value known to be UTC
Attach UTC before asking, or the local zone is used.
from datetime import UTC ts = naive_utc.replace(tzinfo=UTC).timestamp()
Examples
1. Aware UTC
from datetime import datetime, UTC
datetime(2026, 9, 29, 12, tzinfo=UTC).timestamp()
Returns
1790683200.02. Offset does not matter
from datetime import datetime, timedelta, timezone
datetime(2026, 9, 29, 14, tzinfo=timezone(timedelta(hours=2))).timestamp()
Returns
1790683200.03. The epoch is zero
from datetime import datetime, UTC
datetime(1970, 1, 1, tzinfo=UTC).timestamp()
Returns
0.04. Microseconds in the fraction
from datetime import datetime, UTC
datetime(2026, 9, 29, 12, 0, 0, 123456, tzinfo=UTC).timestamp()
Returns
1790683200.1234565. Before 1970 is negative
from datetime import datetime, UTC
datetime(1969, 12, 31, 23, 59, tzinfo=UTC).timestamp()
Returns
-60.06. Exact integer seconds
from datetime import datetime, timedelta, UTC
(datetime(2026, 9, 29, 12, tzinfo=UTC) - datetime(1970, 1, 1, tzinfo=UTC)) // timedelta(seconds=1)
Returns
1790683200Pitfalls
1. timestamp() of a naive UTC value
utcnow()-style naive values are read as LOCAL time, so the result is off by the machine's UTC offset (right only where local time is UTC). Label the value first — then the answer is the same on every machine.
naive (machine-dependent)
from datetime import datetime naive = datetime(2026, 9, 29, 12) naive.tzinfo is None
True
replace(tzinfo=UTC)
from datetime import datetime, UTC datetime(2026, 9, 29, 12).replace(tzinfo=UTC).timestamp()
1790683200.0
2. Calling timestamp() on a date
Only datetime has it. A date has no time of day or zone — pick midnight in a zone explicitly.
date.timestamp()
from datetime import date date(2026, 9, 29).timestamp()
AttributeError: 'datetime.date' object has no attribute 'timestamp'. Did you mean: 'fromtimestamp'?
combine with midnight UTC
from datetime import date, datetime, time, UTC datetime.combine(date(2026, 9, 29), time(), UTC).timestamp()
1790640000.0
When to use
Use it
- Storing or sending instants as numbers
- Interop with time.time(), JavaScript Date, databases with epoch columns
Reach for something else
- Human-readable storage → isoformat()
- Exact integer arithmetic on long spans → subtract datetimes and use timedelta
Notes
CPython impl
Aware: (self - datetime(1970, 1, 1, tzinfo=timezone.utc)).total_seconds(). Naive: the local-time conversion of the platform C library (mktime-like), respecting fold
Precision
A float carries microseconds exactly only up to about 2**33 seconds from the epoch (year 2242)
Reverse
datetime.fromtimestamp(ts, tz) turns the number back into an aware datetime
FAQ
dt.timestamp() on an aware datetime, e.g. datetime(2026, 9, 29, 12, tzinfo=UTC).timestamp() == 1790683200.0. Wrap in int() for whole seconds, or multiply by 1000 for milliseconds.