How to Resolve Python "ValueError: time data '...' does not match format '...'"
The ValueError: time data 'X' does not match format 'Y'
is a common exception encountered when parsing strings into datetime objects using Python's datetime.strptime()
method. It signals a mismatch between the actual structure of your date string ('X'
) and the format code ('Y'
) you provided to interpret it. The parser expects the string to exactly follow the pattern defined by the format code.
This guide explains the common reasons for this mismatch and provides clear solutions to ensure successful date string parsing.
Understanding the Error: strptime
and Format Codes
Python's datetime.strptime(date_string, format)
function works by taking a string (date_string
) and converting it into a datetime
object based on a specific format
pattern you provide. This format
string uses special directive codes (like %Y
for a 4-digit year, %m
for month number, %d
for day, %H
for hour, etc.) to tell the function exactly how the date_string
is structured.
The ValueError
occurs when the parser, following your format
instructions, encounters a part of the date_string
that doesn't align with what the format code expects at that position.
Common Cause 1: Incorrect Directive Order or Value
Swapped Month (%m
) and Day (%d
)
This is very common, especially with ambiguous formats like MM-DD-YYYY
vs. DD-MM-YYYY
. If your format code expects Month-Day but the string provides Day-Month (and the day value is > 12), the error occurs.
from datetime import datetime
# Error Scenario: String is YYYY-DD-MM, but format expects YYYY-MM-DD
date_string = '2025-24-09' # Day 24, Month 09
try:
# ⛔️ ValueError: time data '2025-24-09' does not match format '%Y-%m-%d'
# The format expects month '%m' after the first hyphen, but finds '24'.
dt_object = datetime.strptime(date_string, '%Y-%m-%d')
print(dt_object)
except ValueError as e:
print(e)
# Solution: Correct the format string order to match the data string
# The Format '%Y-%d-%m' correctly matches 'YYYY-DD-MM'
correct_format = '%Y-%d-%m'
dt_object_fixed = datetime.strptime(date_string, correct_format)
print(f"\nCorrectly parsed with '{correct_format}': {dt_object_fixed}")
# Output: Correctly parsed with '%Y-%d-%m': 2025-09-24 00:00:00
Incorrect Year Directive (%y
vs. %Y
)
Using %y
(2-digit year) in the format when the string has a 4-digit year (%Y
), or vice-versa, will cause a mismatch.
from datetime import datetime
date_string_4_year = '2025-09-24'
date_string_2_year = '25-09-24'
# Error Scenario 1: Using %y for a 4-digit year
try:
# ⛔️ ValueError: time data '2025-09-24' does not match format '%y-%m-%d'
# '%y' expects '23', but finds '2025'.
dt_object = datetime.strptime(date_string_4_year, '%y-%m-%d')
print(dt_object)
except ValueError as e:
print(f"Error 1: {e}")
# Solution 1: Use %Y for 4-digit year
# ✅ The correct format uses %Y
dt_object_fixed1 = datetime.strptime(date_string_4_year, '%Y-%m-%d')
print(f"\nParsed '{date_string_4_year}' with '%Y-%m-%d': {dt_object_fixed1}")
# Output: Parsed '2025-09-24' with '%Y-%m-%d': 2025-09-24 00:00:00
# Error Scenario 2: Using %Y for a 2-digit year
try:
# ⛔️ ValueError: time data '25-09-24' does not match format '%Y-%m-%d'
# '%Y' expects 'YYYY', but finds '25'.
dt_object = datetime.strptime(date_string_2_year, '%Y-%m-%d')
print(dt_object)
except ValueError as e:
print(f"Error 2: {e}")
# Solution 2: Use %y for 2-digit year
# ✅ The correct format uses %y
dt_object_fixed2 = datetime.strptime(date_string_2_year, '%y-%m-%d')
print(f"Parsed '{date_string_2_year}' with '%y-%m-%d': {dt_object_fixed2}")
# Output: Parsed '25-09-24' with '%y-%m-%d': 2025-09-24 00:00:00 (Assumes 20xx century)
Common Cause 2: Incorrect Separators or Literal Characters
The format string must include all literal characters (like hyphens -
, slashes /
, spaces
, colons :
) exactly as they appear in the date string.
from datetime import datetime
# Error Scenario: String uses '/', format uses '-'
date_string = "24/09/2025 10:30"
incorrect_format = "%d-%m-%Y %H:%M" # Uses hyphens
try:
# ⛔️ ValueError: time data '24/09/2025 10:30' does not match format '%d-%m-%Y %H:%M'
# Expected '-' after day 24, but found '/'.
dt_object = datetime.strptime(date_string, incorrect_format)
print(dt_object)
except ValueError as e:
print(e)
# Solution: Use matching separators in the format string
# ✅ The correct format uses '/' to match the string
correct_format = "%d/%m/%Y %H:%M"
dt_object_fixed = datetime.strptime(date_string, correct_format)
print(f"\nCorrectly parsed with '{correct_format}': {dt_object_fixed}")
# Output: Correctly parsed with '%d/%m/%Y %H:%M': 2025-09-24 10:30:00
Ensure every non-directive character in your format string corresponds precisely to the character in the same position in the date string.
Common Cause 3: String Contains Extra or Missing Data
The date string must contain exactly the information specified by the format string, and nothing more (unless accounted for).
from datetime import datetime
# Error Scenario 1: String has extra data (timezone abbr.) not in format
date_string_extra = "2025-09-24 10:30:00 EST"
format_str = '%Y-%m-%d %H:%M:%S' # Doesn't account for ' EST'
try:
# ⛔️ ValueError: unconverted data remains: EST
dt_object = datetime.strptime(date_string_extra, format_str)
print(dt_object)
except ValueError as e:
print(f"Error 1: {e}")
# Solution 1: Adjust format to include or ignore extra data (if possible/needed)
# Example: Add '%Z' if timezone abbreviation is always present
# format_str_fixed1 = '%Y-%m-%d %H:%M:%S %Z'
# Or preprocess string to remove extra part if not needed.
# Error Scenario 2: String is missing data expected by format (e.g., seconds)
date_string_missing = "2025-09-24 10:30"
format_str_expects_seconds = '%Y-%m-%d %H:%M:%S' # Expects seconds
try:
# ⛔️ ValueError: time data '2025-09-24 10:30' does not match format '%Y-%m-%d %H:%M:%S'
dt_object = datetime.strptime(date_string_missing, format_str_expects_seconds)
print(dt_object)
except ValueError as e:
print(f"Error 2: {e}")
# Solution 2: Use a format string that matches the available data
format_str_fixed2 = '%Y-%m-%d %H:%M' # Matches the string without seconds
dt_object_fixed2 = datetime.strptime(date_string_missing, format_str_fixed2)
print(f"\nParsed missing seconds OK: {dt_object_fixed2}")
# Output: Parsed missing seconds OK: 2025-09-24 10:30:00
Solution: Ensure Format String Exactly Matches the Date String
The fundamental solution to all these causes is to carefully construct your format
string so that it is an exact template for your date_string
. Every directive (%Y
, %m
, etc.) and every literal character (-
, /
,
, :
) must correspond precisely in order and type to the content of the date string.
Debugging Tips
- Print Both:
print(f"Date String: '{date_string}'")
andprint(f"Format Code: '{format_string}'")
right before thestrptime
call. Visually compare them character by character. - Check Docs: Refer to the official Python documentation for
strftime()
andstrptime()
format codes to ensure you're using the correct directives (%Y
vs%y
,%m
vs%b
, etc.). - Simplify: Start with a simpler format string matching just the beginning of your date string and gradually add more components until it breaks. This helps isolate the mismatch.
- Check for Whitespace: Hidden leading/trailing whitespace in the
date_string
can cause mismatches if not included in theformat
. Usedate_string.strip()
if appropriate.
Alternatives for More Flexible Parsing (Briefly)
If your date strings might have varying formats or are less structured, strptime
's strictness can be challenging. Consider these alternatives:
Using dateutil.parser
The third-party python-dateutil
library offers a very flexible parse()
function that can often guess the format automatically.
# Requires: pip install python-dateutil
from dateutil import parser
try:
dt = parser.parse("24 Sep 2025 10:30 PM")
print(f"dateutil parsed: {dt}") # Output: 2025-09-24 22:30:00
dt2 = parser.parse("2025/09/24")
print(f"dateutil parsed: {dt2}") # Output: 2025-09-24 00:00:00
except ValueError:
print("dateutil failed to parse.")
Using Pandas to_datetime
If using the Pandas library, pd.to_datetime()
is powerful and can infer formats or accept a format
argument similar to strptime
. Setting infer_datetime_format=True
can help performance with consistent formats.
# Requires: pip install pandas
import pandas as pd
try:
dt = pd.to_datetime("2025-09-24 10:30:15.123")
print(f"Pandas parsed: {dt}") # Output: 2025-09-24 10:30:15.123000
# You can also provide format= or set infer_datetime_format=True
# series = pd.to_datetime(df['date_col'], format='%Y/%m/%d', errors='coerce')
except ValueError:
print("Pandas failed to parse.")
These are alternatives to strptime
, not fixes for using strptime
incorrectly.
Conclusion
The ValueError: time data 'X' does not match format 'Y'
arises when using datetime.strptime()
because the provided date_string
does not exactly conform to the structure defined by the format
string. To resolve this error:
- Verify Directive Order: Ensure
%m
,%d
,%Y
, etc., are in the correct sequence corresponding to the date string. - Use Correct Directives: Use
%Y
for 4-digit years,%y
for 2-digit years, and consult docs for others (%H
,%I
,%p
, etc.). - Match Separators and Literals: Ensure all characters like
-
,/
,:
, - Account for All Data: Make sure the format string covers all parts of the date string and doesn't expect data that isn't present.
Carefully aligning the format
string with the date_string
structure is key to successfully using strptime()
.