Presenting dates and times in the right format is crucial for user interfaces, logging, data interchange, and reporting. Python’s datetime module provides powerful methods—strftime() for formatting and strptime() for parsing—to convert between datetime objects and human-readable or standardized string representations. This chapter shows you how to control date and time output, parse custom string inputs, and build your own formatting toolkit.
1. Why Date Formatting Matters
- User Experience: Display dates in a locale-appropriate way (e.g.,
DD/MM/YYYYvs.MM-DD-YYYY). - Data Interchange: Use standardized formats like ISO 8601 (
YYYY-MM-DDThh:mm:ss) for APIs and storage. - Logging & Debugging: Include timestamps in logs consistently to trace issues.
- Parsing Inputs: Convert user-entered date strings into
datetimeobjects for validation and computation.
Formatting bridges the gap between Python’s internal datetime representation and the string formats people or systems expect.
2. Formatting with strftime()
The strftime(format) method on date, time, or datetime objects returns a string formatted according to the given directive codes. Each % code maps to a component of the date/time.
from datetime import datetime
now = datetime.now()
print(now.strftime("%Y-%m-%d %H:%M:%S"))
# Example output: 2025-06-29 14:30:05
Common Format Codes
| Directive | Meaning | Example |
|---|---|---|
%Y | Full year (4 digits) | 2025 |
%m | Month as zero-padded decimal | 06 |
%d | Day of month (01–31) | 29 |
%H | Hour (00–23) | 14 |
%M | Minute (00–59) | 30 |
%S | Second (00–59) | 05 |
%b | Abbreviated month name | Jun |
%B | Full month name | June |
%a | Abbreviated weekday name | Sun |
%A | Full weekday name | Sunday |
Consult the full list of directives in the Python docs for more specialized formatting options【4】.
3. Parsing with strptime()
To convert a date string into a datetime object, use datetime.strptime(string, format), which applies the same directives in reverse. This is essential when accepting dates as text inputs.
from datetime import datetime
date_str = "2025-06-29 14:30:05"
dt = datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")
print(dt, type(dt))
# Output: 2025-06-29 14:30:05 <class 'datetime.datetime'>
If the input string doesn’t match the format exactly, a ValueError is raised. Always validate or handle exceptions when parsing user-supplied dates【5】.
4. ISO 8601 and Built-in Methods
For interoperability, ISO 8601 is the de-facto standard. Python offers shortcuts:
from datetime import datetime
now = datetime.now()
print(now.isoformat()) # e.g., '2025-06-29T14:30:05.123456'
print(now.date().isoformat())# '2025-06-29'
print(now.time().isoformat())# '14:30:05.123456'
Use these methods when you need machine-friendly, unambiguous formats without crafting a custom format string.
5. Handling Locale and Time Zones
- Locale-Aware Formatting:
Thelocalemodule can influence names of months or weekdays when formatting:import locale from datetime import datetime locale.setlocale(locale.LC_TIME, "fr_FR.UTF-8") print(datetime.now().strftime("%A %d %B %Y")) # e.g., 'dimanche 29 juin 2025' - Time Zone Aware Formatting:
For “aware” datetimes withtzinfo, include the%z(UTC offset) or%Z(zone name) directives:from datetime import datetime, timezone utc_now = datetime.now(timezone.utc) print(utc_now.strftime("%Y-%m-%d %H:%M:%S %Z%z")) # e.g., '2025-06-29 14:30:05 UTC+0000'
Always attach a tzinfo to avoid ambiguity in global applications.
6. Formatting Tips and Best Practices
- Define Format Constants:
Store common format strings in variables to ensure consistency:ISO_FMT = "%Y-%m-%dT%H:%M:%S" LOG_FMT = "%Y-%m-%d %H:%M:%S" - Zero Padding & Width Control:
All numeric directives are zero-padded by default (e.g.,%dyields01). No need for manual string manipulation. - Avoid “Magic” Formats in Code:
Document your format strings with comments so future readers understand their purpose. - Validate User Input:
Always wrapstrptime()calls intry/exceptto catch bad inputs and provide clear error messages. - Leverage High-Level Parsing:
For flexible parsing (e.g., variable formats), consider the third-partydateutil.parser.parse()instead of fixedstrptime()【6】.
7. Mini Project: Log Timestamp Formatter
Build a script that reads log entries with ISO timestamps, converts them into a human-friendly format, and writes them out:
# formatter.py
from datetime import datetime
INPUT_LOG = "logs.txt"
OUTPUT_LOG = "formatted_logs.txt"
IN_FORMAT = "%Y-%m-%dT%H:%M:%S"
OUT_FORMAT = "%d %b %Y, %I:%M:%S %p"
def reformat_line(line: str) -> str:
"""
Given a log line starting with an ISO timestamp,
reformat the timestamp to a readable style.
"""
ts_str, _, message = line.partition(" ")
dt = datetime.strptime(ts_str, IN_FORMAT)
human_ts = dt.strftime(OUT_FORMAT)
return f"{human_ts} {message}"
def process_logs():
with open(INPUT_LOG) as fin, open(OUTPUT_LOG, "w") as fout:
for line in fin:
fout.write(reformat_line(line))
if __name__ == "__main__":
process_logs()
IN_FORMATmatches ISO 8601 without fractional seconds.OUT_FORMATproduces29 Jun 2025, 02:30:05 PM.- The script reads
logs.txt, reformats each line, and writes toformatted_logs.txt.
8. Conclusion
Mastering date formatting in Python transforms raw datetime objects into clear, user-oriented strings and back again. With strftime() and strptime(), you can:
- Present dates in any cultural or business format
- Parse user inputs or legacy data files safely
- Leverage ISO 8601 and locale settings
- Keep your code concise and maintainable
Armed with these techniques and best practices, your applications will handle dates and times with precision and clarity. Happy formatting!
Discover more from Affordable Tutor
Subscribe to get the latest posts sent to your email.


