Skip to main content

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}'") and print(f"Format Code: '{format_string}'") right before the strptime call. Visually compare them character by character.
  • Check Docs: Refer to the official Python documentation for strftime() and strptime() 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 the format. Use date_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:

  1. Verify Directive Order: Ensure %m, %d, %Y, etc., are in the correct sequence corresponding to the date string.
  2. Use Correct Directives: Use %Y for 4-digit years, %y for 2-digit years, and consult docs for others (%H, %I, %p, etc.).
  3. Match Separators and Literals: Ensure all characters like -, /, :, , etc., in the format string match those in he date string precisely.
  4. 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().