Working with Dates & Times
Reviewed & published by Brayan K
A datetime in pandas is a special value that stores a precise moment in time, and pandas gives you tools to parse text into datetimes, extract their parts with the .dt accessor, filter by date ranges, and group rows into time buckets.
Part of the free Pandas course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Learn to turn date strings into real dates, pull out the year or weekday, set a DatetimeIndex, resample into monthly totals, and do arithmetic with time spans.
What You'll Learn in This Lesson
- Parse strings with pd.to_datetime()
- Load dates directly with parse_dates
- Pull out parts with the .dt accessor
- Filter rows by a date range
- Set a DatetimeIndex for time series
- Resample into monthly totals and add Timedelta
1 Parsing Dates with pd.to_datetime()
Dates often arrive as plain text. pd.to_datetime() converts a string column into a true datetime64 Series that pandas understands. When reading a CSV you can parse in one step by passing parse_dates=["col"] to pd.read_csv.
import pandas as pd
df = pd.DataFrame({
"order_date": ["2024-01-05", "2024-02-18", "2024-02-29"],
"amount": [100, 250, 75],
})
# Before: order_date is plain text (object dtype)
print(df["order_date"].dtype) # object
# Convert to real datetimes
df["order_date"] = pd.to_datetime(df["order_date"])
print(df["order_date"].dtype) # datetime64[ns]
# When reading a file you could instead write:
# df = pd.read_csv("orders.csv", parse_dates=["order_date"])
# ✅ Expected output:
# object
# datetime64[ns]2 Extracting Parts With the .dt Accessor
Once a column is a datetime, the .dt accessor unlocks its parts: .dt.year, .dt.month, .dt.day, .dt.dayofweek (Monday is 0), and .dt.day_name() for the weekday name. It mirrors the .str accessor you used for text.
import pandas as pd
dates = pd.to_datetime(["2024-01-05", "2024-07-20", "2024-12-25"])
s = pd.Series(dates)
print(s.dt.year.tolist()) # [2024, 2024, 2024]
print(s.dt.month.tolist()) # [1, 7, 12]
print(s.dt.day.tolist()) # [5, 20, 25]
print(s.dt.dayofweek.tolist()) # [4, 5, 2] (Mon=0 .. Sun=6)
print(s.dt.day_name().tolist()) # ['Friday', 'Saturday', 'Wednesday']
# ✅ Expected output:
# [2024, 2024, 2024]
# [1, 7, 12]
# [5, 20, 25]
# [4, 5, 2]
# ['Friday', 'Saturday', 'Wednesday']3 Filtering, Indexing, and Resampling
Because datetimes compare in time order, you can filter a range with normal comparisons. Setting the date column as the index creates a DatetimeIndex, which then lets you resample("M").sum() to roll the data up into monthly totals. Add or subtract spans of time with pd.Timedelta.
import pandas as pd
df = pd.DataFrame({
"date": pd.to_datetime(["2024-01-10", "2024-01-25", "2024-02-08"]),
"sales": [200, 150, 300],
})
# Date-range filter: only January rows
jan = df[(df["date"] >= "2024-01-01") & (df["date"] <= "2024-01-31")]
print(jan["sales"].sum()) # 350
# Set a DatetimeIndex, then resample into monthly totals
monthly = df.set_index("date").resample("M")["sales"].sum()
print(monthly)
# 2024-01-31 -> 350, 2024-02-29 -> 300
# Date arithmetic with Timedelta
deadline = df["date"] + pd.Timedelta(days=30)
print(deadline.tolist())
# ✅ Expected output:
# 350
# date
# 2024-01-31 350
# 2024-02-29 300
# Freq: ME, Name: sales, dtype: int64
# [Timestamp('2024-02-09 00:00:00'), Timestamp('2024-02-24 00:00:00'), Timestamp('2024-03-09 00:00:00')]🎯 Your Turn: Which Year?
Replace the blank so you extract the year from each date. The expected output is the list [2021, 2022, 2023].
import pandas as pd
s = pd.Series(pd.to_datetime(["2021-06-01", "2022-03-15", "2023-11-30"]))
# 🎯 YOUR TURN: get the year part with the .dt accessor
years = s.dt.___
print(years.tolist())
# Expected output: [2021, 2022, 2023]Common Errors
❌ Using .dt on a text column
The .dt accessor only works after conversion. Call pd.to_datetime first.
df["date"] = pd.to_datetime(df["date"])
df["date"].dt.month # ✅ now this works❌ resample without a DatetimeIndex
Set the date column as the index before resampling.
df.set_index("date").resample("M")["sales"].sum() # ✅🎯 Mini Challenge: Weekend Sales
Parse a date column, label each day, and total only the weekend sales.
import pandas as pd
df = pd.DataFrame({
"date": ["2024-03-01", "2024-03-02", "2024-03-03", "2024-03-04"],
"sales": [120, 300, 250, 90],
})
# 1. Parse the dates and add a weekday name column
df["date"] = pd.to_datetime(df["date"])
df["weekday"] = df["date"].dt.day_name()
# 2. Weekend = Saturday or Sunday (dayofweek 5 or 6)
weekend = df[df["date"].dt.dayofweek >= 5]
print(weekend[["weekday", "sales"]])
print("Weekend total:", weekend["sales"].sum()) # 300 + 250 = 550
# ✅ Expected output:
# weekday sales
# 1 Saturday 300
# 2 Sunday 250
# Weekend total: 550❓ Frequently Asked Questions
Lesson complete — time is on your side!
You can parse strings into datetimes, extract any part with .dt, filter by date ranges, set a DatetimeIndex, resample into monthly totals, and add time spans with Timedelta. These skills unlock every time-series analysis.
Practice quiz
Which function converts a column of date strings into datetime64 values?
- pd.parse()
- pd.date()
- pd.to_datetime()
- pd.strptime()
Answer: pd.to_datetime(). pd.to_datetime() parses common date formats and returns a datetime64 Series.
How can you parse dates while reading a CSV in one step?
- pass parse_dates=['col'] to pd.read_csv
- pass dtype='date'
- call .dt after read_csv
- it is impossible
Answer: pass parse_dates=['col'] to pd.read_csv. parse_dates=['col'] in pd.read_csv converts those columns during loading.
What does the .dt accessor give you?
- String methods
- Category codes
- Plotting tools
- The parts of a datetime, like .dt.year and .dt.month
Answer: The parts of a datetime, like .dt.year and .dt.month. .dt exposes datetime parts; it is the datetime equivalent of the .str accessor.
In .dt.dayofweek, what integer represents Monday?
- 1
- 0
- 7
- 6
Answer: 0. dayofweek numbers weekdays 0-6 with Monday as 0 and Sunday as 6.
For 2024-01-05 (a Friday), what does .dt.dayofweek return?
- 4
- 0
- 5
- 1
Answer: 4. With Monday=0, Friday is 4.
What does .dt.day_name() return for 2024-12-25?
- 'December'
- '25'
- 'Wednesday'
- 'Christmas'
Answer: 'Wednesday'. 2024-12-25 falls on a Wednesday, so day_name() returns 'Wednesday'.
What does resample('M').sum() do on a DatetimeIndex?
- Sorts by date
- Rolls the data up into monthly totals
- Drops missing dates
- Converts to strings
Answer: Rolls the data up into monthly totals. resample groups time-series rows into calendar buckets; 'M' with sum gives monthly totals.
What must be true before you can call resample on a DataFrame?
- The values must be integers
- There must be no NaT
- The frame must be sorted
- The index must be a DatetimeIndex
Answer: The index must be a DatetimeIndex. resample needs a DatetimeIndex, so set the date column as the index first.
Why does df['date'].dt.month fail on a plain text column?
- month is not a real attribute
- The .dt accessor only works after pd.to_datetime conversion
- It needs parentheses
- Text columns have no months
Answer: The .dt accessor only works after pd.to_datetime conversion. You must convert to datetime first; .dt only works on datetime columns.
How do you add 30 days to every date in a datetime Series?
- series + 30
- series.add_days(30)
- series + pd.Timedelta(days=30)
- series.dt + 30
Answer: series + pd.Timedelta(days=30). Add a pd.Timedelta(days=30) to shift each datetime by that span.
Continue this course
- Previous: String Operations with .str
- Next: GroupBy: Split-Apply-Combine — Group rows and compute summaries with the split-apply-combine pattern
- Quick reference: Pandas cheat sheet
Frequently asked questions
How do I convert a column of date strings to datetimes in pandas?
Use pd.to_datetime(df['col']). It parses common formats like 2024-01-15 automatically and returns a datetime64 Series. When reading a file you can do this in one step by passing parse_dates=['col'] to pd.read_csv.
What is the .dt accessor used for?
The .dt accessor exposes the parts of a datetime column, so df['date'].dt.year gives the year, .dt.month the month number, .dt.dayofweek the weekday as 0-6, and .dt.day_name() the weekday name. It is the datetime equivalent of the .str accessor for text.
What does resample('M').sum() do?
resample groups time-series rows into regular calendar buckets when the index is a DatetimeIndex. resample('M').sum() collapses the data into monthly totals. It is like groupby, but the groups are time periods such as months, weeks, or years.