Skip to content

pandas to_datetime

Turn strings or numbers into real datetime values you can compute with.

A date that Pandas thinks is a string is barely a date at all. You cannot sort it correctly, subtract one from another, slice a range, or reach for .dt. to_datetime is the conversion that unlocks all of it.

Official documentation: pandas.to_datetime

The forms worth knowing

# Convert a column
pd.to_datetime(df['time'])

# Inside a chain, replacing the column in place
df.assign(time=pd.to_datetime(df['time']))

# State the format when you know it -- faster, and refuses to guess wrong
pd.to_datetime(df['when'], format='%d/%m/%Y')

# Turn unparseable values into NaT instead of raising
pd.to_datetime(df['when'], errors='coerce')

# Unix timestamps
pd.to_datetime(df['epoch'], unit='s')

If you are reading the data in the same breath, prefer parse_dates at load time — it is one step rather than two:

pd.read_csv(url, parse_dates=['time'])

A worked example, on real data

The USGS publishes every earthquake it records as CSV, through a public API with no key — the source Bamboo Weekly #3 worked with.

Read it without parse_dates and the timestamp arrives as text:

import pandas as pd

url = ('https://earthquake.usgs.gov/fdsnws/event/1/query.csv'
       '?starttime=2024-01-01&endtime=2024-12-31&minmagnitude=6')

raw = pd.read_csv(url, usecols=['time', 'place', 'mag'])
raw['time'].dtype
str

Convert it, and the dtype changes to something you can compute with:

(
    raw
    .assign(time=pd.to_datetime(raw['time']))
    .assign(month=pd.col('time').dt.strftime('%B'))
    .loc[pd.col('mag') >= 7.3]
    [['month', 'place', 'mag']]
)
   month                              place  mag
December    24 km WNW of Port-Vila, Vanuatu  7.3
    July 41 km ESE of San Pedro de Ataca...  7.4
   April    15 km S of Hualien City, Taiwan  7.4
 January 2024 Noto Peninsula, Japan Eart...  7.5

The .dt.strftime('%B') in the second line is the point: .dt only exists on a real datetime column. On the string version it raises an AttributeError.

The converted dtype here is datetime64[us, UTC] — microseconds, and timezone-aware because the USGS timestamps carry a Z. Both details matter more in Pandas 3 than they used to; see the videos below.

Three mistakes people make

Letting Pandas guess an ambiguous format. 03/04/2024 is the third of April or the fourth of March depending on where the data came from, and Pandas will pick one — silently, and for every row independently if the format varies. When you know the layout, pass format=. This is not a nicety; guessing wrong corrupts the data quietly.

Letting one bad row raise on the whole column. A single "unknown" in 50,000 timestamps aborts the conversion. errors='coerce' turns unparseable values into NaT, which you can then count and inspect — usually far more useful than a traceback.

Converting after loading when you could convert during. parse_dates in read_csv and read_excel does the same job in one step, and keeps your chain shorter.

Watch it

Two Pandas 3 changes touch this directly: Microseconds vs nanoseconds: datetime64 changes in Pandas 3, which explains the [us] above, and Time zones in Pandas: What Pandas 3 changes (and what it doesn't) for the UTC part. Once your column is a datetime, Pandas time series superpowers shows what it buys you.

Practice it

Work through a to_datetime exercise, with instant feedback and no signup required: practice.lernerpython.com/bamboo-weekly/to-datetime/

Go deeper

Bamboo Weekly is the practice. If you want the structured version — full courses with downloadable Jupyter notebooks, plus live Pandas office hours when you get stuck — that is LernerPython+Data. A paid Bamboo Weekly subscription is included with it.

See it on real data

Below are the 46 Bamboo Weekly exercises that use to_datetime on real-world data — try each one, then study the worked solution.

Part of the Pandas Methods Index. See also practice by skill.