How do I create a datetime in Python from milliseconds?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
If your timestamp is stored as milliseconds since the Unix epoch, Python can convert it to datetime easily once you remember one detail: datetime.fromtimestamp() expects seconds, not milliseconds. The second detail is deciding whether you want a timezone-aware value or a naive local one.
Convert Milliseconds to Seconds First
Epoch milliseconds must be divided by 1000 before they are passed to fromtimestamp().
That is the safest default because the result is timezone-aware and explicitly in UTC.
Why UTC Is Usually the Right Starting Point
If you omit the tz argument, Python gives you a naive datetime in the machine’s local timezone.
That may be fine for a quick local script, but it is risky for services and distributed systems because the meaning depends on server configuration. UTC keeps the original instant unambiguous.
Convert to a Local Zone Later
Once you have a UTC-aware datetime, you can convert it to any target zone.
This is usually better than creating a naive local time directly because you preserve the actual point in time first.
Alternative: Add timedelta to the Epoch
Some developers prefer to make the epoch math explicit.
This is equivalent and can be easier to read when you want the conversion logic to emphasize the unit.
Parse String Milliseconds Carefully
Millisecond timestamps often arrive as strings from JSON, logs, or query parameters. Parse them to integers first.
Keeping that parse step explicit makes invalid input easier to catch.
Going Back to Milliseconds
Sometimes you need the reverse conversion after modifying the datetime.
That round-trip is useful for APIs and databases that store epoch milliseconds as integers.
Decide the Time Semantics Once
The conversion code is easy. The harder part is deciding what the resulting datetime should mean in the rest of the system. If your application stores UTC internally, make that the rule everywhere and convert to local display zones only at the edges.
That discipline prevents a lot of debugging pain later, especially when timestamps move between services, logs, and user-facing interfaces.
Common Pitfalls
The biggest mistake is passing the millisecond value directly to fromtimestamp() without dividing by 1000. That makes Python interpret the value as seconds.
Another issue is mixing naive local datetimes with timezone-aware UTC datetimes in the same application.
A third problem is using utcfromtimestamp() and then forgetting that the result is still naive rather than explicitly timezone-aware.
Summary
- Divide epoch milliseconds by
1000before usingdatetime.fromtimestamp(). - Prefer
tz=timezone.utcfor an aware UTC result. - Convert to local zones after creating the unambiguous UTC value.
- Parse string timestamps with
int()before conversion. - Keep naive and aware datetimes consistent across the codebase.

