mirror of
https://github.com/python/cpython.git
synced 2025-12-31 04:23:37 +00:00
[3.14] gh-70647: Better promote how to safely parse yearless dates in datetime. (GH-116179) (#143037)
gh-70647: Better promote how to safely parse yearless dates in datetime. (GH-116179)
* gh-70647: Better promote how to safely parse yearless dates in datetime.
Every four years people encounter this because it just isn't obvious.
This moves the footnote up to a note with a code example.
We'd love to change the default year value for datetime but doing
that could have other consequences for existing code. This documented
workaround *always* works.
* doctest code within note is bad, dedent.
* Update to match the error message.
* remove no longer referenced footnote
* ignore the warning in the doctest
* use Petr's suggestion for the docs to hide the warning processing
* cover date.strptime (3.14) as well
(cherry picked from commit b8d3fddba6)
Co-authored-by: Gregory P. Smith <68491+gpshead@users.noreply.github.com>
This commit is contained in:
parent
27648a1818
commit
362d11e545
1 changed files with 37 additions and 6 deletions
|
|
@ -2634,9 +2634,42 @@ Broadly speaking, ``d.strftime(fmt)`` acts like the :mod:`time` module's
|
|||
``time.strftime(fmt, d.timetuple())`` although not all objects support a
|
||||
:meth:`~date.timetuple` method.
|
||||
|
||||
For the :meth:`.datetime.strptime` class method, the default value is
|
||||
``1900-01-01T00:00:00.000``: any components not specified in the format string
|
||||
will be pulled from the default value. [#]_
|
||||
For the :meth:`.datetime.strptime` and :meth:`.date.strptime` class methods,
|
||||
the default value is ``1900-01-01T00:00:00.000``: any components not specified
|
||||
in the format string will be pulled from the default value.
|
||||
|
||||
.. note::
|
||||
When used to parse partial dates lacking a year, :meth:`.datetime.strptime`
|
||||
and :meth:`.date.strptime` will raise when encountering February 29 because
|
||||
the default year of 1900 is *not* a leap year. Always add a default leap
|
||||
year to partial date strings before parsing.
|
||||
|
||||
|
||||
.. testsetup::
|
||||
|
||||
# doctest seems to turn the warning into an error which makes it
|
||||
# show up and require matching and prevents the actual interesting
|
||||
# exception from being raised.
|
||||
# Manually apply the catch_warnings context manager
|
||||
import warnings
|
||||
catch_warnings = warnings.catch_warnings()
|
||||
catch_warnings.__enter__()
|
||||
warnings.simplefilter("ignore")
|
||||
|
||||
.. testcleanup::
|
||||
|
||||
catch_warnings.__exit__()
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> from datetime import datetime
|
||||
>>> value = "2/29"
|
||||
>>> datetime.strptime(value, "%m/%d")
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: day 29 must be in range 1..28 for month 2 in year 1900
|
||||
>>> datetime.strptime(f"1904 {value}", "%Y %m/%d")
|
||||
datetime.datetime(1904, 2, 29, 0, 0)
|
||||
|
||||
Using ``datetime.strptime(date_string, format)`` is equivalent to::
|
||||
|
||||
|
|
@ -2767,7 +2800,7 @@ Notes:
|
|||
include a year in the format. If the value you need to parse lacks a year,
|
||||
append an explicit dummy leap year. Otherwise your code will raise an
|
||||
exception when it encounters leap day because the default year used by the
|
||||
parser is not a leap year. Users run into this bug every four years...
|
||||
parser (1900) is not a leap year. Users run into that bug every leap year.
|
||||
|
||||
.. doctest::
|
||||
|
||||
|
|
@ -2794,5 +2827,3 @@ Notes:
|
|||
.. [#] See R. H. van Gent's `guide to the mathematics of the ISO 8601 calendar
|
||||
<https://web.archive.org/web/20220531051136/https://webspace.science.uu.nl/~gent0113/calendar/isocalendar.htm>`_
|
||||
for a good explanation.
|
||||
|
||||
.. [#] Passing ``datetime.strptime('Feb 29', '%b %d')`` will fail since 1900 is not a leap year.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue