Pandas
Python
datetime
data manipulation
data analysis

How to change the datetime format in Pandas

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Pandas provides several ways to change datetime formats: pd.to_datetime() converts strings to datetime objects, dt.strftime() formats datetime objects back to strings, and dt accessor properties extract individual components like year, month, and day. The key distinction is between the internal datetime representation (used for calculations) and the display format (used for output). Always store dates as datetime objects and only format them as strings for display or export.

Converting Strings to Datetime

python
1import pandas as pd
2
3df = pd.DataFrame({
4    "date_str": ["2025-03-02", "2025-06-15", "2025-12-25"]
5})
6
7# Auto-detect format
8df["date"] = pd.to_datetime(df["date_str"])
9print(df["date"].dtype)  # datetime64[ns]
10
11# Specify format explicitly (faster for large datasets)
12df["date"] = pd.to_datetime(df["date_str"], format="%Y-%m-%d")

Specifying the format parameter avoids the overhead of format inference and prevents ambiguous parsing (e.g., is 01/02/03 January 2 or February 1?).

Common String-to-Datetime Conversions

python
1# Various input formats
2dates = pd.Series([
3    "March 2, 2025",
4    "02/03/2025",
5    "2025.03.02",
6    "02-Mar-2025",
7    "20250302"
8])
9
10# Auto-detect works for most formats
11parsed = pd.to_datetime(dates)
12print(parsed)
13
14# Explicit formats for ambiguous dates
15pd.to_datetime("02/03/2025", format="%m/%d/%Y")  # March 2
16pd.to_datetime("02/03/2025", format="%d/%m/%Y")  # February 3
17
18# Handle errors
19pd.to_datetime(["2025-01-01", "not a date", "2025-03-15"],
20               errors="coerce")  # Invalid → NaT

errors="coerce" converts unparseable values to NaT (Not a Time) instead of raising an error.

Formatting Datetime to String

python
1df = pd.DataFrame({
2    "date": pd.to_datetime(["2025-03-02", "2025-06-15", "2025-12-25"])
3})
4
5# Format as string
6df["formatted"] = df["date"].dt.strftime("%B %d, %Y")
7print(df["formatted"])
8# 0      March 02, 2025
9# 1       June 15, 2025
10# 2    December 25, 2025
11
12# Common format codes
13df["iso"] = df["date"].dt.strftime("%Y-%m-%d")          # 2025-03-02
14df["us"] = df["date"].dt.strftime("%m/%d/%Y")            # 03/02/2025
15df["eu"] = df["date"].dt.strftime("%d/%m/%Y")            # 02/03/2025
16df["short"] = df["date"].dt.strftime("%d-%b-%Y")         # 02-Mar-2025
17df["with_time"] = df["date"].dt.strftime("%Y-%m-%d %H:%M:%S")

Format Code Reference

CodeMeaningExample
%Y4-digit year2025
%y2-digit year25
%mMonth (zero-padded)03
%BMonth nameMarch
%bAbbreviated monthMar
%dDay (zero-padded)02
%HHour (24-hour)14
%IHour (12-hour)02
%MMinute30
%SSecond45
%pAM/PMPM
%ADay nameSunday
%aAbbreviated daySun

Extracting Date Components

python
1df = pd.DataFrame({
2    "date": pd.to_datetime(["2025-03-02 14:30:00", "2025-06-15 09:15:00"])
3})
4
5df["year"] = df["date"].dt.year           # 2025
6df["month"] = df["date"].dt.month         # 3, 6
7df["day"] = df["date"].dt.day             # 2, 15
8df["hour"] = df["date"].dt.hour           # 14, 9
9df["weekday"] = df["date"].dt.day_name()  # Sunday, Sunday
10df["quarter"] = df["date"].dt.quarter     # 1, 2
11df["week"] = df["date"].dt.isocalendar().week  # ISO week number

Changing the Datetime Index Format

python
1# Set datetime as index
2df = pd.DataFrame(
3    {"value": [100, 200, 300]},
4    index=pd.to_datetime(["2025-01-01", "2025-02-01", "2025-03-01"])
5)
6
7# The index displays as datetime
8print(df.index)
9# DatetimeIndex(['2025-01-01', '2025-02-01', '2025-03-01'], dtype='datetime64[ns]')
10
11# Format index for display
12df.index = df.index.strftime("%B %Y")
13print(df.index)
14# Index(['January 2025', 'February 2025', 'March 2025'], dtype='object')
15# Warning: index is now strings, not datetime — arithmetic won't work

Handling Timezones

python
1df = pd.DataFrame({
2    "date": pd.to_datetime(["2025-03-02 14:30:00"])
3})
4
5# Add timezone
6df["date_utc"] = df["date"].dt.tz_localize("UTC")
7
8# Convert to another timezone
9df["date_eastern"] = df["date_utc"].dt.tz_convert("US/Eastern")
10
11# Format with timezone
12df["formatted"] = df["date_eastern"].dt.strftime("%Y-%m-%d %H:%M %Z")
13print(df["formatted"][0])  # 2025-03-02 09:30 EST

Reading Dates from CSV

python
1# Parse dates during read
2df = pd.read_csv("data.csv", parse_dates=["date_column"])
3
4# Specify date format
5df = pd.read_csv("data.csv", parse_dates=["date_column"],
6                  date_format="%d/%m/%Y")
7
8# Multiple date columns
9df = pd.read_csv("data.csv", parse_dates=["start_date", "end_date"])

Parsing dates during read_csv is faster than converting after loading because it avoids creating intermediate string objects.

Common Pitfalls

  • Confusing datetime objects with formatted strings: After dt.strftime(), the column contains strings, not datetimes. You cannot perform date arithmetic (timedelta addition, comparison) on formatted strings. Keep the datetime column for calculations and create a separate formatted column for display.
  • Ambiguous date formats without explicit format: pd.to_datetime("01/02/03") is ambiguous — is it January 2, 2003 or February 1, 2003? Always specify the format parameter for non-ISO date strings to avoid silent misinterpretation.
  • Using errors="coerce" without checking for NaT: Coercing bad dates to NaT silently hides data quality issues. After conversion, check df["date"].isna().sum() to see how many values failed to parse.
  • Formatting the DatetimeIndex and losing datetime functionality: Converting a DatetimeIndex to strings with strftime() makes resampling, slicing, and time-based operations impossible. Only format for final output, never for intermediate processing.
  • Performance with pd.to_datetime on large datasets: Without a format parameter, pandas tries multiple formats for each row. On millions of rows, specifying the format explicitly can be 10x faster.

Summary

  • Use pd.to_datetime() to convert strings to datetime objects — always specify format for non-ISO dates
  • Use dt.strftime() to format datetime objects as display strings
  • Use dt.year, dt.month, dt.day accessors to extract date components
  • Keep datetime columns as datetime64 for calculations — only convert to strings for output
  • Use parse_dates in pd.read_csv() for efficient date parsing during file loading
  • Set errors="coerce" to convert bad dates to NaT, but always check for missing values afterward

Course illustration
Course illustration

All Rights Reserved.