Visitar URL original
GH-70647: Deprecate strptime day of month parsing without a year present to avoid leap-year bugs by gpshead · Pull Request #117107 · python/cpython · GitHub
Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Document the behavior deprecation.
  • Loading branch information
gpshead committed Mar 29, 2024
commit 333ba5789d638650cf4ec41c47c29ce22d43aaa5
33 changes: 33 additions & 0 deletions Doc/library/datetime.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1079,6 +1079,24 @@ Other constructors, all class methods:
time tuple. See also :ref:`strftime-strptime-behavior` and
:meth:`datetime.fromisoformat`.

.. versionchanged:: 3.13

If *format* specifies a day of month without a year a
:exc:`DeprecationWarning` is now emitted. This is to avoid a quadrennial
leap year bug in code seeking to parse only a month and day as the
default year used in absence of one in the format is not a leap year.
Such *format* values may raise an error as of Python 3.15. The
workaround is to always include a year in your *format*. If parsing
*date_string* values that do not have a year, explicitly add a year that
is a leap year before parsing:

.. doctest::

>>> from datetime import datetime
>>> date_string = "02/29"
>>> when = datetime.strptime(f"{date_string};1984", "%m/%d;%Y")
>>> when.strftime("%B %d") # doctest: +SKIP
Comment thread
pganssle marked this conversation as resolved.
'February 29'


Class attributes:
Expand Down Expand Up @@ -2657,6 +2675,21 @@ Notes:
for formats ``%d``, ``%m``, ``%H``, ``%I``, ``%M``, ``%S``, ``%j``, ``%U``,
``%W``, and ``%V``. Format ``%y`` does require a leading zero.

(10)
When parsing a month and day using :meth:`~.datetime.strptime`, always
include a year in the format. If the value you need to parse lacks a year,
just append an explicit dummy leap year. Otherwise your code will raise an
exception when it encounters leap day as the default year used by the parser
is not a leap year. Users run into this bug every four years...

>>> strptime(f"{month_day};1984", "%m/%d;%Y") # problem mitigated!

.. deprecated-removed:: 3.13 3.15
:meth:`~.datetime.strptime` calls using a format string containing
a day of month without a year now emit a
:exc:`DeprecationWarning`. In 3.15 or later we may change this into
an error or change the default year to a leapyear. See :gh:`70647`.

.. rubric:: Footnotes

.. [#] If, that is, we ignore the effects of Relativity
Expand Down