From: Jason Yalim, PhD <4813268+jyalim@users.noreply.github.com> Date: Mon, 16 Feb 2026 22:20:37 +0000 (-0700) Subject: gh-140715: Add `%D` format code support to `strptime()` (GH-144819) X-Git-Tag: v3.15.0a7~266 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=185a6e942af3e44b3bdb2bdcf2d55c0a6208f89b;p=thirdparty%2FPython%2Fcpython.git gh-140715: Add `%D` format code support to `strptime()` (GH-144819) * %D support for strptime, including test and Doc update * additional %D test * change documentation example date for %D so it is more legible to non-US readers * change testing date for %D so it is more legible to non-US readers * mv News blurb to Library, consistent with previous %F change * change invalid format code from %D to C-standard unused %! * Fix erroneous and misleading example Doc to %y from %Y, use correct C99+ definition for C99 %D; update additional tests --------- Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> --- diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index d861139cec6d..39a7a1530a95 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -2534,8 +2534,8 @@ requires, and these work on all supported platforms. | ``%d`` | Day of the month as a | 01, 02, ..., 31 | \(9) | | | zero-padded decimal number. | | | +-----------+--------------------------------+------------------------+-------+ -| ``%D`` | Equivalent to ``%m/%d/%y``. | 11/10/2025 | \(9), | -| | | | \(0) | +| ``%D`` | Equivalent to ``%m/%d/%y``. | 11/28/25 | \(9) | +| | | | | +-----------+--------------------------------+------------------------+-------+ | ``%e`` | The day of the month as a | ␣1, ␣2, ..., 31 | | | | space-padded decimal number. | | | @@ -2676,7 +2676,7 @@ differences between platforms in handling of unsupported format specifiers. ``%:z`` was added for :meth:`~.datetime.strftime`. .. versionadded:: 3.15 - ``%:z`` and ``%F`` were added for :meth:`~.datetime.strptime`. + ``%:z``, ``%F``, and ``%D`` were added for :meth:`~.datetime.strptime`. Technical Detail ^^^^^^^^^^^^^^^^ diff --git a/Lib/_strptime.py b/Lib/_strptime.py index 8b62ea734b7d..fe34808d8876 100644 --- a/Lib/_strptime.py +++ b/Lib/_strptime.py @@ -418,6 +418,7 @@ class TimeRE(dict): mapping['W'] = mapping['U'].replace('U', 'W') base.__init__(mapping) + base.__setitem__('D', self.pattern('%m/%d/%y')) base.__setitem__('F', self.pattern('%Y-%m-%d')) base.__setitem__('T', self.pattern('%H:%M:%S')) base.__setitem__('R', self.pattern('%H:%M')) diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index 3784909ee778..97eec618932a 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -2200,6 +2200,13 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase): self.theclass.strptime(test_date, "%Y-%m-%d") ) + def test_strptime_D_format(self): + test_date = "11/28/25" + self.assertEqual( + self.theclass.strptime(test_date, "%D"), + self.theclass.strptime(test_date, "%m/%d/%y") + ) + ############################################################################# # datetime tests diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py index 0784ea6a4cf5..fd8525feb88d 100644 --- a/Lib/test/test_strptime.py +++ b/Lib/test/test_strptime.py @@ -286,7 +286,7 @@ class StrptimeTests(unittest.TestCase): def test_strptime_exception_context(self): # check that this doesn't chain exceptions needlessly (see #17572) with self.assertRaises(ValueError) as e: - _strptime._strptime_time('', '%D') + _strptime._strptime_time('', '%!') self.assertTrue(e.exception.__suppress_context__) # additional check for stray % branch with self.assertRaises(ValueError) as e: @@ -663,6 +663,13 @@ class StrptimeTests(unittest.TestCase): time.strptime(test_time, "%H:%M:%S") ) + def test_strptime_D_format(self): + test_date = "11/28/25" + self.assertEqual( + time.strptime(test_date, "%D"), + time.strptime(test_date, "%m/%d/%y") + ) + class Strptime12AMPMTests(unittest.TestCase): """Test a _strptime regression in '%I %p' at 12 noon (12 PM)""" diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index da0cf494bfa8..da5fd16b8b62 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -358,7 +358,7 @@ class TimeTestCase(unittest.TestCase): # Should be able to go round-trip from strftime to strptime without # raising an exception. tt = time.gmtime(self.t) - for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'F', 'H', 'I', + for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'D', 'F', 'H', 'I', 'j', 'm', 'M', 'p', 'S', 'T', 'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'): format = '%' + directive @@ -379,7 +379,7 @@ class TimeTestCase(unittest.TestCase): def test_strptime_exception_context(self): # check that this doesn't chain exceptions needlessly (see #17572) with self.assertRaises(ValueError) as e: - time.strptime('', '%D') + time.strptime('', '%!') self.assertTrue(e.exception.__suppress_context__) # additional check for stray % branch with self.assertRaises(ValueError) as e: diff --git a/Misc/NEWS.d/next/Library/2026-02-14-14-56-44.gh-issue-140715.AbSheM.rst b/Misc/NEWS.d/next/Library/2026-02-14-14-56-44.gh-issue-140715.AbSheM.rst new file mode 100644 index 000000000000..f7782f2fa4f2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-14-14-56-44.gh-issue-140715.AbSheM.rst @@ -0,0 +1 @@ +Add ``'%D'`` support to :meth:`~datetime.datetime.strptime`.