]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-140715: Add `%D` format code support to `strptime()` (GH-144819)
authorJason Yalim, PhD <4813268+jyalim@users.noreply.github.com>
Mon, 16 Feb 2026 22:20:37 +0000 (15:20 -0700)
committerGitHub <noreply@github.com>
Mon, 16 Feb 2026 22:20:37 +0000 (14:20 -0800)
* %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>
Doc/library/datetime.rst
Lib/_strptime.py
Lib/test/datetimetester.py
Lib/test/test_strptime.py
Lib/test/test_time.py
Misc/NEWS.d/next/Library/2026-02-14-14-56-44.gh-issue-140715.AbSheM.rst [new file with mode: 0644]

index d861139cec6db54f26d9c74cf27baa407ce3c017..39a7a1530a95ccb4a9699a470ccab850584491ff 100644 (file)
@@ -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
 ^^^^^^^^^^^^^^^^
index 8b62ea734b7d1172c68687e4fcd2ea15e275b06d..fe34808d88769a44c93c56d62049388b8eeed824 100644 (file)
@@ -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'))
index 3784909ee77839f4405f9c4c54f6eb685d0f24a8..97eec618932aa56624d473565916a584336f9508 100644 (file)
@@ -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
index 0784ea6a4cf5d42e09e2a357019998e1293db9c6..fd8525feb88d53373efec035e37a6a6e5c16e30e 100644 (file)
@@ -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)"""
 
index da0cf494bfa8ad6ed690c34e6e43ef9b6c28f706..da5fd16b8b62910c1ff9185fd4a06e2cab603296 100644 (file)
@@ -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 (file)
index 0000000..f7782f2
--- /dev/null
@@ -0,0 +1 @@
+Add ``'%D'`` support to :meth:`~datetime.datetime.strptime`.