diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index 1ce2013f05da2e..b6c6e1f69be528 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -2765,6 +2765,15 @@ Notes: :exc:`DeprecationWarning`. In 3.15 or later we may change this into an error or change the default year to a leap year. See :gh:`70647`. +(11) + When parsing a string using :meth:`~.datetime.strptime`, if more than one + directive of the same time unit is used, a SyntaxWarning is raised as + only the last directive gets parsed and applied to the datetime object. For + example, if the format string contains both ``%Y`` and ``%y``, like ``%Y%y``, + only the last directive of the string (``%y``) gets used on the resulting + datetime object. + + .. rubric:: Footnotes .. [#] If, that is, we ignore the effects of Relativity diff --git a/Lib/_strptime.py b/Lib/_strptime.py index aa63933a49d16d..59d3f7b3cf1b84 100644 --- a/Lib/_strptime.py +++ b/Lib/_strptime.py @@ -357,12 +357,15 @@ def pattern(self, format): day_of_month_in_format = False def repl(m): format_char = m[1] + nonlocal year_in_format, day_of_month_in_format match format_char: case 'Y' | 'y' | 'G': - nonlocal year_in_format + if year_in_format: + import warnings + warnings.warn("When using conflicting directives only the last one will be used.", + SyntaxWarning, skip_file_prefixes=(os.path.dirname(__file__),)) year_in_format = True case 'd': - nonlocal day_of_month_in_format day_of_month_in_format = True return self[format_char] format = re_sub(r'%([OE]?\\?.?)', repl, format) diff --git a/Misc/NEWS.d/next/Library/2025-04-14-18-18-00.gh-issue-124549.hcsdgf.rst b/Misc/NEWS.d/next/Library/2025-04-14-18-18-00.gh-issue-124549.hcsdgf.rst new file mode 100644 index 00000000000000..24197ab185c504 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-04-14-18-18-00.gh-issue-124549.hcsdgf.rst @@ -0,0 +1,2 @@ +Raise a warning in :func:`datetime.datetime.strptime` and :func:`datetime.date.strptime` +when conflicting directives are provided.