How to Reformat Datetime Strings in Python
Converting dates between formats is essential for data integration, API communication, and database operations. Whether you're transforming "December 31, 2024" into "2024-12-31" for database storage or converting ISO timestamps into human-friendly displays, Python's datetime module provides reliable tools for parsing and reformatting date strings. This guide walks you through the core techniques and common patterns for datetime string manipulation.
The Parse-Then-Format Pattern
Reformatting dates requires two steps: parsing the original string into a datetime object, then formatting that object into your desired output. The strptime() method handles parsing, while strftime() handles formatting:
from datetime import datetime
# Original date string
original = "31-Dec-2025 23:59:59"
# Step 1: Parse string into datetime object
dt = datetime.strptime(original, "%d-%b-%Y %H:%M:%S")
# Step 2: Format datetime object into new string
reformatted = dt.strftime("%Y/%m/%d %H:%M")
print(f"Original: {original}")
print(f"Reformatted: {reformatted}")
# Output: "2025/12/31 23:59"
Output:
Original: 31-Dec-2025 23:59:59
Reformatted: 2025/12/31 23:59
- strptime: String Parse Time (input)
- strftime: String Format Time (output)
Essential Format Codes
Understanding format codes is crucial for accurate parsing and formatting:
| Code | Meaning | Example |
|---|---|---|
%Y | 4-digit year | 2024 |
%y | 2-digit year | 24 |
%m | Month (zero-padded) | 05 |
%B | Full month name | December |
%b | Abbreviated month | Dec |
%d | Day of month | 31 |
%H | Hour (24-hour) | 23 |
%I | Hour (12-hour) | 11 |
%M | Minute | 59 |
%S | Second | 45 |
%p | AM/PM | PM |
The most common datetime bug is confusing %m (month) with %M (minute). Both are lowercase letters but represent completely different values. Always verify your format strings carefully.
Common Format Conversions
from datetime import datetime
# Parse a date string
dt = datetime.strptime("2025-12-31 14:30:00", "%Y-%m-%d %H:%M:%S")
# Various output formats
print(dt.strftime("%d/%m/%Y")) # 31/12/2025
print(dt.strftime("%B %d, %Y")) # December 31, 2025
print(dt.strftime("%Y%m%d")) # 20251231
print(dt.strftime("%I:%M %p")) # 02:30 PM
print(dt.strftime("%A, %B %d")) # Wednesday, December 31
print(dt.strftime("%Y-%m-%dT%H:%M:%SZ")) # 2025-12-31T14:30:00Z
Handling Multiple Input Formats
When processing data from various sources, you may encounter different date formats:
from datetime import datetime
def parse_flexible_date(date_string):
"""Try multiple formats to parse a date string."""
formats = [
"%Y-%m-%d",
"%d/%m/%Y",
"%m/%d/%Y",
"%B %d, %Y",
"%d-%b-%Y",
"%Y%m%d"
]
for fmt in formats:
try:
return datetime.strptime(date_string, fmt)
except ValueError:
continue
raise ValueError(f"Unable to parse date: {date_string}")
# Test with different formats
dates = ["2025-12-31", "31/12/2025", "December 31, 2025"]
for date_str in dates:
dt = parse_flexible_date(date_str)
print(f"{date_str} → {dt.strftime('%Y-%m-%d')}")
Output:
2025-12-31 → 2025-12-31
31/12/2025 → 2025-12-31
December 31, 2025 → 2025-12-31
Batch Processing with Pandas
For large datasets, Pandas offers optimized datetime handling:
import pandas as pd
# Sample data with mixed date formats
data = {
"event": ["Launch", "Update", "Release"],
"date": ["2024-01-15", "2024-06-30", "2024-12-31"]
}
df = pd.DataFrame(data)
# Convert string column to datetime
df["date"] = pd.to_datetime(df["date"])
# Reformat to different string format
df["formatted"] = df["date"].dt.strftime("%B %d, %Y")
print(df)
Pandas' to_datetime() can often infer date formats automatically, making it excellent for cleaning messy real-world data. Add format= parameter for explicit control and better performance.
Reusable Reformatting Function
from datetime import datetime
def reformat_date(date_string, input_format, output_format):
"""
Convert a date string from one format to another.
Args:
date_string: The original date string
input_format: Format of the input string
output_format: Desired output format
Returns:
Reformatted date string
"""
dt = datetime.strptime(date_string, input_format)
return dt.strftime(output_format)
# Usage examples
print(reformat_date("31-12-2025", "%d-%m-%Y", "%Y/%m/%d"))
# Output: 2025/12/31
print(reformat_date("Dec 31, 2025", "%b %d, %Y", "%Y-%m-%d"))
# Output: 2025-12-31
Working with Timezones
For timezone-aware datetime handling:
from datetime import datetime
from zoneinfo import ZoneInfo # Python 3.9+
# Parse and add timezone
dt = datetime.strptime("2025-12-31 14:30:00", "%Y-%m-%d %H:%M:%S")
dt_utc = dt.replace(tzinfo=ZoneInfo("UTC"))
# Convert to different timezone
dt_eastern = dt_utc.astimezone(ZoneInfo("America/New_York"))
print(f"UTC: {dt_utc.strftime('%Y-%m-%d %H:%M %Z')}")
print(f"Eastern: {dt_eastern.strftime('%Y-%m-%d %H:%M %Z')}")
Output:
UTC: 2025-12-31 14:30 UTC
Eastern: 2025-12-31 09:30 EST
Ensure your input format string exactly matches your date string, including separators, spacing, and punctuation. A mismatch causes ValueError exceptions.
By mastering the parse-and-format pattern, you can reliably convert datetime strings between any formats required by your databases, APIs, or user interfaces.