When you work with dates and times in Python, you often need to display them to users or read date strings from files and APIs. The datetime module covers both directions: strftime formats a date as a string, and strptime parses a string into a datetime object.
from datetime import datetime
now = datetime.now()
print(now.strftime("%B %d, %Y")) # July 12, 2026strftime stands for "string from time". You pass a format string full of percent codes, and Python replaces each code with the matching part of the date. Here %B becomes the full month name, %d the zero-padded day, and %Y the four-digit year.
strftime: format a date as a string
The strftime method works on the date, datetime, and time objects you create when you work with dates and times in Python. You build a format string by mixing literal characters with format codes that start with a percent sign.
from datetime import datetime
event = datetime(2026, 12, 25, 18, 30)
print(event.strftime("%Y-%m-%d")) # 2026-12-25
print(event.strftime("%A, %B %d")) # Friday, December 25
print(event.strftime("%I:%M %p")) # 06:30 PMEach format code pulls one piece of information out of the datetime. Literal characters such as dashes, commas, colons, and spaces pass through to the output unchanged.
Common strftime format codes
This table covers the codes you will use most often in real programs, with the value each one produces for Sunday, July 12, 2026 at 14:30:05.
| Code | Meaning | Example |
|---|---|---|
| %Y | Four-digit year | 2026 |
| %y | Two-digit year | 26 |
| %m | Zero-padded month | 07 |
| %B | Full month name | July |
| %b | Abbreviated month name | Jul |
| %d | Zero-padded day of month | 12 |
| %A | Full weekday name | Sunday |
| %a | Abbreviated weekday name | Sun |
| %H | 24-hour hour, zero-padded | 14 |
| %I | 12-hour hour, zero-padded | 02 |
| %M | Zero-padded minute | 30 |
| %S | Zero-padded second | 05 |
| %p | AM or PM | PM |
| %j | Day of year, 001 to 366 | 193 |
| %W | Week number, Monday as first day | 27 |
You can combine the codes in any order to build the exact output you need. A few patterns show up constantly in real code:
from datetime import datetime
dt = datetime(2026, 7, 12, 14, 30, 5)
print(dt.strftime("%m/%d/%Y")) # 07/12/2026
print(dt.strftime("%d-%b-%Y")) # 12-Jul-2026
print(dt.strftime("%A, %B %d, %Y at %I:%M %p")) # Sunday, July 12, 2026 at 02:30 PMThe first two are compact numeric styles, and the third is a full human-readable sentence built from the same building blocks.
strptime: parse a string into a datetime
strptime, short for "string parse time", does the reverse. It reads a date string plus a format that describes the string's structure, and returns a datetime object.
from datetime import datetime
parsed = datetime.strptime("2026-07-12", "%Y-%m-%d")
print(parsed) # 2026-07-12 00:00:00
print(type(parsed)) # <class 'datetime.datetime'>The format "%Y-%m-%d" tells Python to expect a four-digit year, a dash, a two-digit month, another dash, and a two-digit day. Any time component you do not supply defaults to zero, which is why the result lands at midnight.
Parsing different date formats
The format string must match the input exactly, because spaces, punctuation, and code order all matter.
from datetime import datetime
print(datetime.strptime("12/07/2026", "%d/%m/%Y")) # 2026-07-12 00:00:00
print(datetime.strptime("July 12, 2026", "%B %d, %Y")) # 2026-07-12 00:00:00
print(datetime.strptime("12-Jul-2026 14:30", "%d-%b-%Y %H:%M")) # 2026-07-12 14:30:00Each call produces the same date, July 12, 2026, but reads a different input style. The third call also captures the time because its format includes the hour and minute codes.
A mismatch between the string and the format is a hard error rather than a wrong guess. When they do not line up, strptime raises a ValueError:
from datetime import datetime
datetime.strptime("2026-07-12", "%d/%m/%Y")
# ValueError: time data '2026-07-12' does not match format '%d/%m/%Y'The input uses dashes but the format expects slashes, so parsing fails immediately. Failing loudly is useful here, because a silent wrong guess would corrupt your data.
ISO 8601 format
The ISO 8601 standard, YYYY-MM-DD for dates and YYYY-MM-DDTHH:MM:SS for datetimes, is the most common machine-readable date format. The Python standard library supports it directly, with no format codes needed.
from datetime import date, datetime
print(date.today().isoformat()) # 2026-07-12
print(date.fromisoformat("2026-12-25")) # 2026-12-25
print(datetime.fromisoformat("2026-07-12T14:30:00")) # 2026-07-12 14:30:00isoformat produces the standard string and fromisoformat parses it back. Use this pair when saving dates to JSON, writing to a database, or exchanging data between systems, because the format is unambiguous and widely supported.
Practical example: parsing a user-supplied date
A common real-world task is accepting a date string that may arrive in one of several styles. Trying a list of formats in order handles that cleanly.
from datetime import datetime
def parse_date(date_string):
formats = ["%Y-%m-%d", "%m/%d/%Y", "%d-%b-%Y"]
for fmt in formats:
try:
return datetime.strptime(date_string, fmt).date()
except ValueError:
continue
raise ValueError(f"Cannot parse date: {date_string}")
print(parse_date("07/12/2026")) # 2026-07-12The function tries each format until one succeeds, then returns a date object. If nothing matches, it raises its own error, which is the right behavior when the input truly cannot be understood.
Building readable timestamps
Format codes shine when you need timestamps for logs, filenames, or display text.
from datetime import datetime
now = datetime.now()
print(now.strftime("[%Y-%m-%d %H:%M:%S]")) # [2026-07-12 14:30:05]
print(now.strftime("report_%Y%m%d_%H%M%S.txt")) # report_20260712_143005.txt
print(now.strftime("%A, %B %d, %Y")) # Sunday, July 12, 2026The first line is a typical log prefix and the last is a display style. For filenames, avoid spaces and colons, and prefer compact codes like %Y%m%d so the names sort correctly.
Common mistakes
Four mistakes cause most date formatting bugs in practice.
Swapping %m and %d. The format %m/%d/%Y means month first, in the US style, while %d/%m/%Y means day first, used in most other regions. The wrong order often produces a valid-looking but wrong date, so always confirm which style your input uses.
Using %y instead of %Y. Two-digit years are ambiguous about the century. Prefer %Y unless you are forced to handle two-digit year data.
Forgetting that strptime needs an exact match. A single misplaced space or wrong separator raises a ValueError. When parsing fails, print the input string and the format string side by side to spot the mismatch.
Calling strptime on an instance. strptime is a class method, so write datetime.strptime(text, fmt) rather than calling it on an existing datetime value.
Rune AI
Key Insights
strftime()converts a datetime object to a formatted string using format codes like%Y,%m, and%d.strptime()parses a string into a datetime object by matching format codes to the string's structure.- Common format codes:
%Y(4-digit year),%m(month),%d(day),%H(24-hour),%I(12-hour),%M(minute),%S(second),%p(AM/PM). - Use
isoformat()andfromisoformat()for standard YYYY-MM-DD strings. - The format string must match the date string exactly when using
strptime, or you will get aValueError.
Frequently Asked Questions
What is the difference between strftime and strptime?
What does the %Y format code do?
How do I handle dates in different languages or locales?
Conclusion
strftime and strptime are the two essential methods for moving between datetime objects and human-readable strings. Memorize the most common format codes and keep a reference for the rest. When you need a standard machine-readable format, use isoformat for output and fromisoformat for input.
More in this topic
What Is the Python Standard Library?
Learn what the Python standard library is, why it matters, and how to use its built-in modules without installing anything extra.
Encode and Decode Base64 Data in Python
Learn how to use Python's base64 module to encode binary data as text and decode Base64 strings back to bytes.
Python `math` Module Explained
Learn how to use the Python math module for square roots, rounding, trigonometry, logarithms, and mathematical constants.