Day of Month in strptime Requires Year in Python 3.15

Day of Month in strptime Requires Year in Python 3.15

When strptime parses a string, any components not specified in the format are filled in using default values. A format without a year produces a date in 1900, which is rarely what the caller intended and is not stated anywhere in the code. This choice also has a practical consequence: because 1900 is not a leap year, 29 February cannot be parsed when the year is omitted.

For example, a format that specifies a day of month but no year:

from datetime import datetime

print(datetime.strptime('15', '%d'))
print(datetime.strptime('02/15', '%m/%d'))

On Python 3.14 still produces a result, but with deprecation:

intro.py:3: DeprecationWarning: Parsing dates involving a day of month without a year specified is ambiguous
1900-01-15 00:00:00
intro.py:4: DeprecationWarning: Parsing dates involving a day of month without a year specified is ambiguous
1900-02-15 00:00:00

Both calls succeed, and both return a date in a year that was never supplied.

Since Python 3.15, the call is now rejected instead of silently assuming a year. Note that the restriction applies to the day of month only. A format such as %m continues to work on its own, since a month without a year is unambiguous, unlike a day of the month.

ValueError: Day of month directive '%d' may not be used without a year directive

The fix is to include a year directive in both the input and the format:

from datetime import datetime

print(datetime.strptime('15/2026', '%d/%Y'))  # 2026-01-15 00:00:00
print(datetime.strptime('02/15/2026', '%m/%d/%Y'))  # 2026-02-15 00:00:00

Leave a Comment

Cancel reply

Your email address will not be published.