Pandas strftime(): Format Dates and Times

Format Pandas timestamps, date indexes and Series as text. Practise directives, missing dates, timezones and fiscal-period labels.

Format the original month-end date range 🔝

strftime() formats dates as text. Use DatetimeIndex.strftime(), Timestamp.strftime() or Series.dt.strftime(); there is no DataFrame.strftime(). The original October 2019 to February 2020 example uses the current ME month-end alias and unambiguous ISO input dates.
import pandas as pd
dates = pd.date_range(start="2019-10-20", end="2020-02-14", freq="ME")
formatted = dates.strftime("%d-%b-%Y")
print(formatted)
assert len(formatted) == 4
assert dates[0] == pd.Timestamp("2019-10-31")

Expected output

Index(['31-Oct-2019', '30-Nov-2019', '31-Dec-2019', '31-Jan-2020'], dtype='str')

Use a portable numeric format 🔝

Month and weekday names depend on the runtime locale. Numeric year-month-day formats are suitable when a stable output convention is needed.
iso = dates.strftime("%Y-%m-%d")
print(iso.tolist())
assert iso.tolist() == ["2019-10-31", "2019-11-30", "2019-12-31", "2020-01-31"]

Expected output

['2019-10-31', '2019-11-30', '2019-12-31', '2020-01-31']

Date and time directives 🔝

DirectiveMeaning
%a / %AAbbreviated / full weekday name; locale dependent.
%wWeekday number, Sunday 0 to Saturday 6.
%W / %UWeek number with Monday / Sunday first; days before the first such weekday are week 00.
%d / %jDay of month / day of year.
%b / %B / %mAbbreviated month / full month / numeric month.
%y / %YTwo-digit / full calendar year.
%H / %I24-hour / 12-hour clock.
%M / %SMinute / second.
%pAM/PM; locale dependent.
%fMicroseconds, not a fiscal year for datetime values.
%z / %ZUTC offset / timezone name.
%x / %X / %cLocale-specific date / time / combined display.

The original fiscal-year and quarter entries need object-specific treatment: Period.strftime() supports %q, %f and %F; DatetimeIndex/Series datetime formatting does not provide the same fiscal-period semantics. Use the period example below. Directive support can also vary by operating system; prefer explicit numeric directives for exchange formats.

Format one timestamp and its components 🔝

Preserve the original hour, minute, second, weekday and day-of-year topics. This fixed synthetic timestamp keeps the example repeatable.
stamp = pd.Timestamp("2026-09-05 14:35:20.123456")
print(stamp.strftime("%Y-%m-%d %H:%M:%S.%f"))
print("Weekday/day of year:", stamp.strftime("%w %j"))
print("Week numbers:", stamp.strftime("%W %U"))
assert stamp.strftime("%H:%M:%S") == "14:35:20"

Expected output

2026-09-05 14:35:20.123456
Weekday/day of year: 6 248
Week numbers: 35 35

Format a DataFrame date column with dt 🔝

Parse source text first with to_datetime(). Keep the datetime column for sorting and calculations; add a separate display column.
table = pd.DataFrame({"date_text": ["2026-09-05", "invalid", None]})
table["date"] = pd.to_datetime(table["date_text"], format="%Y-%m-%d", errors="coerce")
table["display_date"] = table["date"].dt.strftime("%d/%m/%Y").astype("string")
print(table)
assert table["date"].isna().sum() == 2
assert table["display_date"].iloc[0] == "05/09/2026"

Expected output

    date_text       date display_date
0  2026-09-05 2026-09-05   05/09/2026
1     invalid        NaT         <NA>
2         NaN        NaT         <NA>

Choose an explicit missing-date display 🔝

Formatting does not repair failed dates. A display label can help readers while the source and missing datetime remain available for review.
display = table["display_date"].fillna("Needs review")
print(display.tolist())
assert display.tolist() == ["05/09/2026", "Needs review", "Needs review"]

Expected output

['05/09/2026', 'Needs review', 'Needs review']

Convert timezone before formatting 🔝

Format an aware timestamp after selecting the intended timezone. Text alone is insufficient for timezone calculations.
utc = pd.Timestamp("2026-09-05 09:00:00", tz="UTC")
local = utc.tz_convert("Asia/Kolkata")
print(local.strftime("%Y-%m-%d %H:%M %z %Z"))
assert local.strftime("%H:%M %z") == "14:30 +0530"

Expected output

2026-09-05 14:30 +0530 IST

Format fiscal periods and quarters 🔝

Keep the original fiscal-year and quarter concepts using the appropriate Period object. Q-MAR describes a fiscal year ending in March. These period aliases differ from timestamp month/quarter-end offset aliases.
period = pd.Period("2026-05", freq="Q-MAR")
print(period.strftime("Fiscal %F, short year %f, quarter %q"))
assert period.strftime("%F Q%q") == "2027 Q1"

Expected output

Fiscal 2027, short year 27, quarter 1

Common mistakes 🔝

Do not call DataFrame.strftime(), confuse %m (month) with %M (minute), or replace datetime columns with display strings before calculations. %b, %A, %p and local %x/%X/%c depend on locale. Do not infer fiscal years from datetime %f. See period_range() for period sequences and date_range() for timestamp sequences.

Exercise: create report labels 🔝

Create two daily timestamps starting 2026-09-05, format them as YYYYMMDD, and verify that the underlying dates are unchanged. Continue with Date and Time exercises.

Exercise solution 🔝

Keep the date sequence separate from its display labels.
report_dates = pd.date_range("2026-09-05", periods=2, freq="D")
labels = report_dates.strftime("%Y%m%d")
print(labels.tolist())
assert labels.tolist() == ["20260905", "20260906"]
assert report_dates[0] == pd.Timestamp("2026-09-05")

Expected output

['20260905', '20260906']

Practice in Google Colab 🔝

Open in Google Colab View on GitHub

Run examples in order, inspect formatted dates and try the exercise. Save a copy to keep edits.

Reference: Pandas strftime() documentation.




Subscribe to our YouTube Channel here



plus2net.com







Python Video Tutorials
Python SQLite Video Tutorials
Python MySQL Video Tutorials
Python Tkinter Video Tutorials
✖
We use cookies to improve your browsing experience. . Learn more
HTML MySQL PHP JavaScript ASP Photoshop Articles Contact us
© 2000-2026 plus2net.com All rights reserved worldwide Privacy Policy Disclaimer