How to change the date format in Python
Master Python date formatting. Discover multiple methods, tips, real-world examples, and how to debug common errors.

To format dates in Python is a common task for developers. It helps with data manipulation and user interface design. Python's modules offer powerful tools for this purpose.
You'll explore several techniques to handle date formats, with practical tips for real-world applications. This article also provides advice for common errors to help you master date manipulation.
Basic date formatting with datetime.strftime
from datetime import datetime
date_obj = datetime.now()
formatted_date = date_obj.strftime("%Y-%m-%d")
print(formatted_date)--OUTPUT--2023-10-15
The strftime() method is your primary tool for converting a datetime object into a custom-formatted string. It's essential for creating user-friendly date representations or for standardizing data for storage.
The magic happens in the format string, "%Y-%m-%d", where each code specifies a part of the date:
%Yrepresents the full four-digit year.%mgives you the zero-padded month (01-12).%dprovides the zero-padded day of the month (01-31).
This approach gives you granular control over the final output, ensuring dates appear exactly as you need them.
Common date formatting techniques
Building on what you've learned with strftime(), you can also parse date strings, work with the time module, and apply various custom separators.
Using datetime.strptime to convert string formats
from datetime import datetime
date_string = "Oct 15, 2023"
date_obj = datetime.strptime(date_string, "%b %d, %Y")
new_format = date_obj.strftime("%d/%m/%Y")
print(new_format)--OUTPUT--15/10/2023
While strftime() formats a date object as a string, strptime() does the reverse. It parses a date string into a datetime object, which is useful when you're working with date data from external sources like APIs or files.
The key is matching the format codes to the input string. For "Oct 15, 2023", the format string "%b %d, %Y" breaks down like this:
%bmatches the abbreviated month name (e.g., "Oct").%dcorresponds to the day of the month.%Yrepresents the four-digit year.
Once parsed, you have a standard datetime object that you can reformat however you need.
Formatting with the time module
import time
timestamp = time.time()
formatted_time = time.strftime("%H:%M:%S %d-%m-%Y", time.localtime(timestamp))
print(formatted_time)--OUTPUT--12:30:45 15-10-2023
Besides datetime, Python's time module provides a more fundamental way to manipulate time. It often works with Unix timestamps, which are the number of seconds since the epoch. You get the current timestamp with time.time(). To format it, you first convert this raw number into a time structure using time.localtime().
From there, time.strftime() formats the structure into a string. The format codes are the same as with datetime, but here are the ones specific to time:
%H: Hour, presented in a 24 hour format%M: Minute, from 00 to 59%S: Second, from 00 to 61 to account for leap seconds
Using different date separators and formats
from datetime import datetime
date_obj = datetime.now()
formats = ["%Y.%m.%d", "%Y/%m/%d", "%Y-%m-%d", "%d-%b-%Y"]
for fmt in formats:
print(date_obj.strftime(fmt))--OUTPUT--2023.10.15
2023/10/15
2023-10-15
15-Oct-2023
The flexibility of strftime() extends to the separators you use between date components. You aren't limited to hyphens. You can use periods, slashes, or any other character to structure your date string as needed.
"%Y.%m.%d"uses periods for a clean, numerical look."%Y/%m/%d"is a common format using slashes."%d-%b-%Y"changes the order and uses the abbreviated month name.
This demonstrates how you can combine different format codes and separators to achieve virtually any date representation you require.
Advanced date formatting approaches
When the built-in tools aren't quite enough, you can tackle more complex date challenges using powerful libraries and direct arithmetic on datetime objects.
Using dateutil.parser for flexible parsing
from dateutil import parser
date_string = "15 October 2023"
date_obj = parser.parse(date_string)
print(date_obj.strftime("%Y-%m-%d %H:%M:%S"))--OUTPUT--2023-10-15 0:00:00
The dateutil library is a powerful third-party tool that simplifies parsing date strings. Unlike strptime(), where you must specify the exact format, dateutil.parser.parse() intelligently handles a wide variety of string formats automatically.
- It can recognize common date representations like
"15 October 2023"without any format codes. - This makes it incredibly useful when dealing with data from different sources where date formats might be inconsistent.
Once parsed, you get a standard datetime object you can format as usual.
Converting multiple dates with pandas
import pandas as pd
dates = ["2023-10-15", "2023/10/16", "Oct 17, 2023"]
series = pd.to_datetime(dates)
print(series.dt.strftime("%d-%m-%Y"))--OUTPUT--0 15-10-2023
1 16-10-2023
2 17-10-2023
dtype: object
For handling dates in bulk, especially from data files, the pandas library is a game-changer. The pd.to_datetime() function is incredibly powerful. It takes a list of date strings in various formats and converts them all into a consistent datetime format, which is perfect for data analysis.
- It processes the entire list at once, so you don't need to write a loop.
- Once you have a pandas Series of dates, you can use the
.dtaccessor. This lets you apply methods likestrftime()to every date in the collection simultaneously.
Working with datetime arithmetic and formatting
from datetime import datetime, timedelta
date_obj = datetime.now()
tomorrow = date_obj + timedelta(days=1)
formatted = tomorrow.strftime("%A, %B %d, %Y")
print(formatted)--OUTPUT--Monday, October 16, 2023
You can perform calculations directly on datetime objects using the timedelta class. A timedelta object represents a duration—like days, hours, or seconds—that you can add to or subtract from a date.
- The code creates a
timedeltafor one day and adds it to the current date to calculate tomorrow. - This arithmetic results in a new
datetimeobject for the future date. - You can then format this new object into a readable string with
strftime(), using codes like%Afor the full weekday and%Bfor the full month name.
Move faster with Replit
Replit is an AI-powered development platform that transforms natural language into working applications. Describe what you want to build, and Replit Agent creates it—complete with databases, APIs, and deployment.
For the date formatting techniques you've just learned, Replit Agent can turn them into production-ready tools. You can build:
- A date format converter that accepts various string inputs, like
"Oct 15, 2023"or"2023/10/15", and outputs them in a standardized format. - An event countdown dashboard that calculates the remaining days, hours, and minutes to a specific deadline.
- A data cleaning utility that ingests files with inconsistent date columns and standardizes them using the power of
pandas.
Try Replit Agent by describing your app idea. It writes the code, tests it, and fixes issues automatically, all in your browser.
Common errors and challenges
Even with powerful tools, you might run into a few common pitfalls when formatting dates in Python.
- Mixing up
strftime()andstrptime()functions: A frequent mistake is confusing these two functions. Remember thatstrftime()creates a string from a date object, whilestrptime()parses a string to create one. Using the wrong function will cause anAttributeError, as you can't callstrftime()on a string. - Using incorrect format specifiers: When parsing a string with
strptime(), the format codes must perfectly match the input. If your code expects%Y-%m-%dbut receives a date like"October 15, 2023", Python will raise aValueErrorbecause the structure doesn't align. - Comparing timezone-aware and naive datetime objects: Python distinguishes between "naive" datetime objects, which have no timezone information, and "aware" objects, which do. Trying to compare or perform math between them will trigger a
TypeError. Always ensure your objects are consistent before operations by making them all aware or all naive.
Mixing up strftime() and strptime() functions
A common slip-up is using strftime() when you mean to use strptime(). Remember, strftime() formats a date object into a string. If you try to give it a string to parse, Python will raise an AttributeError. Check out the code below to see what happens.
from datetime import datetime
# Incorrectly trying to parse a string using strftime instead of strptime
date_string = "2023-10-15"
try:
date_obj = datetime.strftime(date_string, "%Y-%m-%d")
print(date_obj)
except Exception as e:
print(f"Error: {e}")
The code triggers an error because it calls strftime() on the datetime class with a string argument. This function is a method that must be called on a datetime object, not the class itself. See the corrected approach below.
from datetime import datetime
# Correctly using strptime to parse a string into a datetime object
date_string = "2023-10-15"
date_obj = datetime.strptime(date_string, "%Y-%m-%d")
print(date_obj)
The fix works because it uses datetime.strptime(), the correct function for parsing a string into a datetime object. This error often surfaces when you're processing date strings from external sources like files or APIs. To avoid it, remember the distinction: you use strptime() to convert a string to a date object and strftime() to format a date object into a string. This simple rule will keep your date handling code error-free.
Using incorrect format specifiers
Using the wrong format specifier can lead to subtle bugs. A simple mix-up, like using %y for a two-digit year instead of %Y for a four-digit year, won't cause a crash but will format your date incorrectly. The following code shows this in action.
from datetime import datetime
# Using wrong format code (lowercase y instead of uppercase Y for 4-digit year)
date_obj = datetime.now()
formatted_date = date_obj.strftime("%y-%m-%d")
print(formatted_date) # Will print with 2-digit year like "23-10-15"
Using %y results in a two-digit year, creating potentially misleading output. This kind of error is tricky because it doesn't stop the code from running. See how a minor change to the format string prevents this ambiguity.
from datetime import datetime
# Using correct format code (uppercase Y for 4-digit year)
date_obj = datetime.now()
formatted_date = date_obj.strftime("%Y-%m-%d")
print(formatted_date) # Will print with 4-digit year like "2023-10-15"
The fix is simple: using the uppercase %Y specifier ensures the full four-digit year appears in the output. This prevents ambiguity, which is critical when your data needs to be clear and standardized for things like logs or database entries. Always double-check your format codes to avoid these silent bugs. A small typo like using %y instead of %Y won't crash your code but can lead to misinterpreted data down the line.
Comparing timezone-aware and naive datetime objects
A frequent source of errors is mixing timezone-aware and naive datetime objects. Since naive objects lack timezone data, Python can't logically compare them to aware objects. This mismatch will raise a TypeError. The following code shows what happens when you try.
from datetime import datetime
import pytz
# Creating a naive and a timezone-aware datetime
naive_dt = datetime.now()
aware_dt = datetime.now(pytz.UTC)
# This comparison raises TypeError
try:
if naive_dt > aware_dt:
print("Naive datetime is later")
else:
print("Aware datetime is later")
except TypeError as e:
print(f"Error: {e}")
The code triggers the error by attempting to use the > operator to compare a naive datetime object with a timezone-aware one. Python can't resolve this ambiguity. See how to fix this by making both objects consistent.
from datetime import datetime
import pytz
# Creating a naive and a timezone-aware datetime
naive_dt = datetime.now()
aware_dt = datetime.now(pytz.UTC)
# Convert naive to aware for proper comparison
utc = pytz.UTC
aware_local_dt = utc.localize(naive_dt)
# Now comparison works
if aware_local_dt > aware_dt:
print("Local datetime is later")
else:
print("UTC datetime is later")
The fix is to make both datetime objects consistent before you compare them. The solution uses the pytz library's localize() method to convert the naive object into a timezone-aware one. By attaching a timezone, you give Python the context it needs to perform the comparison correctly, preventing the TypeError. You'll often run into this when handling dates from different sources, like databases and external APIs, which might not be consistent.
Real-world applications
Correct date formatting is essential for real-world applications, such as creating dynamic log filenames or filtering events based on their timestamps.
Creating log filenames with datetime.strftime
Using strftime() to create timestamped log filenames is a common practice that helps keep your logs organized and easy to navigate.
from datetime import datetime
def generate_log_filename():
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
return f"application_log_{timestamp}.txt"
log_filename = generate_log_filename()
print(f"New log file created: {log_filename}")
This function, generate_log_filename(), creates a unique filename every time it's called. It works by capturing the current moment with datetime.now() and then formatting it into a precise string.
- The
strftime()method uses the format"%Y%m%d_%H%M%S"to create a timestamp that includes the year, month, day, and the exact time. - An f-string then embeds this timestamp into a filename, resulting in a distinct name like
application_log_20231015_123045.txtfor each execution, preventing overwrites.
Filtering events with datetime comparisons
Applying datetime comparisons lets you filter collections of data, such as pulling all events from a list that occur between two specific dates.
from datetime import datetime
events = [
("Meeting", "2023-10-10"),
("Conference", "2023-10-15"),
("Workshop", "2023-10-20"),
("Interview", "2023-10-25")
]
start_date = datetime.strptime("2023-10-14", "%Y-%m-%d")
end_date = datetime.strptime("2023-10-21", "%Y-%m-%d")
filtered_events = [
event for event, date_str in events
if start_date <= datetime.strptime(date_str, "%Y-%m-%d") <= end_date
]
print("Events between 14-21 Oct:", filtered_events)
This snippet shows how to process a list of events using a compact list comprehension. It first establishes a date range by parsing two strings into datetime objects with datetime.strptime().
- The list comprehension iterates through each event, converting its date string into a temporary
datetimeobject on the fly. - It then uses a chained comparison with the
<=operator to check if an event's date falls within the defined range. - Only the names of events that meet the criteria are added to the final list.
Get started with Replit
Put your new skills to use by building a real tool. Describe what you want to Replit Agent, like “build a date converter for multiple formats” or “create a countdown dashboard to a specific date.”
It writes the code, tests for errors, and deploys your app. See your idea come to life in minutes. Start building with Replit.
Create and deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.
Create & deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.



