Date Formatting in Python

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/YYYY vs. 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 datetime objects 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

DirectiveMeaningExample
%YFull year (4 digits)2025
%mMonth as zero-padded decimal06
%dDay of month (01–31)29
%HHour (00–23)14
%MMinute (00–59)30
%SSecond (00–59)05
%bAbbreviated month nameJun
%BFull month nameJune
%aAbbreviated weekday nameSun
%AFull weekday nameSunday

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:
    The locale module 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 with tzinfo, 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

  1. 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"
  2. Zero Padding & Width Control:
    All numeric directives are zero-padded by default (e.g., %d yields 01). No need for manual string manipulation.
  3. Avoid “Magic” Formats in Code:
    Document your format strings with comments so future readers understand their purpose.
  4. Validate User Input:
    Always wrap strptime() calls in try/except to catch bad inputs and provide clear error messages.
  5. Leverage High-Level Parsing:
    For flexible parsing (e.g., variable formats), consider the third-party dateutil.parser.parse() instead of fixed strptime()【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()
  1. IN_FORMAT matches ISO 8601 without fractional seconds.
  2. OUT_FORMAT produces 29 Jun 2025, 02:30:05 PM.
  3. The script reads logs.txt, reformats each line, and writes to formatted_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.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top