When I first started working with timestamps in Python, I saw a number like 1719820800 and had no idea what to do with it. It looked like a random integer. In reality, it was 2024-07-01 00:00:00 UTC, and Python can convert it in one line.

This guide covers the two approaches you will use most often: the standard library's datetime.fromtimestamp() and Pandas' pd.to_datetime(). They solve the same problem but for different kinds of work.

What You Are Converting

A Unix timestamp is the number of seconds since 1970-01-01 00:00:00 UTC. For example:

1719820800

represents:

2024-07-01 00:00:00 UTC

Before converting anything, check whether your value is in seconds or milliseconds. The difference is three zeros, and it is the source of most conversion errors.

Type Example
Seconds 1719820800
Milliseconds 1719820800000

Converting with datetime.fromtimestamp()

For single timestamps or application logic, the built-in datetime module is usually enough.

from datetime import datetime

timestamp = 1719820800
dt = datetime.fromtimestamp(timestamp)
print(dt)

Output:

2024-07-01 08:00:00

Wait — why 08:00:00 instead of 00:00:00?

Because datetime.fromtimestamp() converts to your local system time. If your machine is set to UTC+8, the same UTC moment appears eight hours later in local time. This is the first trap most beginners hit.

To get UTC explicitly:

from datetime import datetime, timezone

dt = datetime.fromtimestamp(1719820800, tz=timezone.utc)
print(dt)

Output:

2024-07-01 00:00:00+00:00

I recommend always passing tz=timezone.utc when you want UTC, rather than trusting the server's local timezone setting.

Converting with Pandas

When you have a list, a Series, or an entire DataFrame, Pandas is the better choice.

import pandas as pd

timestamp = 1719820800
dt = pd.to_datetime(timestamp, unit="s")
print(dt)

Output:

2024-07-01 00:00:00

Two things matter here:

  1. Always specify the unit. unit="s" means seconds. Without it, Pandas may interpret the number as nanoseconds.
  2. Pandas defaults to UTC-like behavior for integer timestamps, which is why the output shows 00:00:00 rather than local time.

Converting a List or Column

import pandas as pd

timestamps = [1719820800, 1719907200, 1719993600]
dates = pd.to_datetime(timestamps, unit="s")
print(dates)

Output:

DatetimeIndex(['2024-07-01', '2024-07-02', '2024-07-03'], dtype='datetime64[ns]', freq=None)

For a DataFrame column:

df = pd.DataFrame({
    "timestamp": [1719820800, 1719907200]
})

df["date"] = pd.to_datetime(df["timestamp"], unit="s")
print(df)

Output:

    timestamp       date
0  1719820800 2024-07-01
1  1719907200 2024-07-02

This is much cleaner than looping through rows with datetime.fromtimestamp().

datetime vs Pandas: Which Should You Use?

The choice depends on what you are doing:

  • Use datetime.fromtimestamp() for application logic, single values, and scripts where you do not want a heavy dependency.
  • Use pd.to_datetime() for data analysis, DataFrames, CSV processing, and time-series work.
Scenario Use
Single timestamp in a script datetime
Backend API logic datetime
DataFrame column conversion Pandas
Time-series analysis Pandas
Large CSV import Pandas

Seconds vs Milliseconds

If your timestamp has 13 digits instead of 10, it is milliseconds:

# Wrong — unit="s" on a millisecond value will overflow
pd.to_datetime(1719820800000, unit="s")

# Correct
pd.to_datetime(1719820800000, unit="ms")

With datetime:

datetime.fromtimestamp(1719820800000 / 1000, tz=timezone.utc)

The rule is the same everywhere: 10 digits means seconds, 13 digits means milliseconds.

Common Mistakes

Forgetting the Unit

pd.to_datetime(1719820800)

Without unit="s", Pandas may treat the value as nanoseconds and return a date far in the future or an overflow error. Always be explicit.

Ignoring Timezones

datetime.fromtimestamp() without a timezone argument returns local time. That means the same code can produce different results on different machines. If your server is in Virginia and your colleague's laptop is in Shanghai, you will see different outputs.

The fix is simple:

from datetime import datetime, timezone

# Always UTC
datetime.fromtimestamp(ts, tz=timezone.utc)

# Or explicitly local
import pytz
datetime.fromtimestamp(ts, tz=pytz.timezone("Asia/Shanghai"))

Using datetime for Large Datasets

This works but does not scale:

for ts in timestamps:
    datetime.fromtimestamp(ts)

For thousands or millions of rows, use Pandas. It is faster and easier to maintain.

Conclusion

Both datetime.fromtimestamp() and pd.to_datetime() convert Unix timestamps to readable dates, but they serve different purposes. Use datetime for application logic and single values. Use Pandas for data processing and analysis.

Before converting any timestamp, ask yourself:

  1. Is it in seconds or milliseconds?
  2. Does timezone handling matter?
  3. Am I converting one value or a whole dataset?

Those three questions will save you from most Python timestamp bugs.

Bonus: Converting Back to a Timestamp

Sometimes you need the reverse operation: take a datetime or Pandas Timestamp and get the Unix seconds back.

With datetime:

from datetime import datetime, timezone

dt = datetime(2024, 7, 1, 0, 0, 0, tzinfo=timezone.utc)
ts = int(dt.timestamp())
print(ts)  # 1719820800

With Pandas:

import pandas as pd

pd_ts = pd.Timestamp('2024-07-01', tz='UTC')
ts = int(pd_ts.timestamp())
print(ts)  # 1719820800

One thing to watch for: calling .timestamp() on a naive datetime uses the system local timezone. I always make timestamps timezone-aware before converting them, even if the timezone is UTC. It removes the silent dependency on the server's locale settings.

For quick conversions without writing code, use the FastUnix Timestamp Converter.