We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
There was an error while loading. Please reload this page.
2 parents b581777 + 18c04f2 commit 820e28cCopy full SHA for 820e28c
Doc/library/datetime.rst
@@ -2534,8 +2534,8 @@ requires, and these work on all supported platforms.
2534
| ``%d`` | Day of the month as a | 01, 02, ..., 31 | \(9) |
2535
| | zero-padded decimal number. | | |
2536
+-----------+--------------------------------+------------------------+-------+
2537
-| ``%D`` | Equivalent to ``%m/%d/%y``. | 11/10/2025 | \(9), |
2538
-| | | | \(0) |
+| ``%D`` | Equivalent to ``%m/%d/%y``. | 11/28/25 | \(9) |
+| | | | |
2539
2540
| ``%e`` | The day of the month as a | ␣1, ␣2, ..., 31 | |
2541
| | space-padded decimal number. | | |
@@ -2676,7 +2676,7 @@ differences between platforms in handling of unsupported format specifiers.
2676
``%:z`` was added for :meth:`~.datetime.strftime`.
2677
2678
.. versionadded:: 3.15
2679
- ``%:z`` and ``%F`` were added for :meth:`~.datetime.strptime`.
+ ``%:z``, ``%F``, and ``%D`` were added for :meth:`~.datetime.strptime`.
2680
2681
Technical Detail
2682
^^^^^^^^^^^^^^^^
Lib/_ast_unparse.py
@@ -239,11 +239,11 @@ def visit_NamedExpr(self, node):
239
self.traverse(node.value)
240
241
def visit_Import(self, node):
242
- self.fill("import ")
+ self.fill("lazy import " if node.is_lazy else "import ")
243
self.interleave(lambda: self.write(", "), self.traverse, node.names)
244
245
def visit_ImportFrom(self, node):
246
- self.fill("from ")
+ self.fill("lazy from " if node.is_lazy else "from ")
247
self.write("." * (node.level or 0))
248
if node.module:
249
self.write(node.module)
Lib/_strptime.py
@@ -418,6 +418,7 @@ def __init__(self, locale_time=None):
418
mapping['W'] = mapping['U'].replace('U', 'W')
419
420
base.__init__(mapping)
421
+ base.__setitem__('D', self.pattern('%m/%d/%y'))
422
base.__setitem__('F', self.pattern('%Y-%m-%d'))
423
base.__setitem__('T', self.pattern('%H:%M:%S'))
424
base.__setitem__('R', self.pattern('%H:%M'))
Lib/test/datetimetester.py
@@ -2200,6 +2200,13 @@ def test_strptime_F_format(self):
2200
self.theclass.strptime(test_date, "%Y-%m-%d")
2201
)
2202
2203
+ def test_strptime_D_format(self):
2204
+ test_date = "11/28/25"
2205
+ self.assertEqual(
2206
+ self.theclass.strptime(test_date, "%D"),
2207
+ self.theclass.strptime(test_date, "%m/%d/%y")
2208
+ )
2209
+
2210
2211
#############################################################################
2212
# datetime tests
Lib/test/pickletester.py
@@ -3202,6 +3202,7 @@ def test_builtin_exceptions(self):
3202
'ExceptionGroup': (3, 11),
3203
'_IncompleteInputError': (3, 13),
3204
'PythonFinalizationError': (3, 13),
3205
+ 'ImportCycleError': (3, 15),
3206
}
3207
for t in builtins.__dict__.values():
3208
if isinstance(t, type) and issubclass(t, BaseException):
@@ -3228,6 +3229,7 @@ def test_builtin_functions(self):
3228
3229
'breakpoint': (3, 7),
3230
'aiter': (3, 10),
3231
'anext': (3, 10),
3232
+ '__lazy_import__': (3, 15),
3233
3234
3235
if isinstance(t, types.BuiltinFunctionType):
Lib/test/test_strptime.py
@@ -286,7 +286,7 @@ def test_ValueError(self):
286
def test_strptime_exception_context(self):
287
# check that this doesn't chain exceptions needlessly (see #17572)
288
with self.assertRaises(ValueError) as e:
289
- _strptime._strptime_time('', '%D')
+ _strptime._strptime_time('', '%!')
290
self.assertTrue(e.exception.__suppress_context__)
291
# additional check for stray % branch
292
@@ -663,6 +663,13 @@ def test_strptime_T_format(self):
663
time.strptime(test_time, "%H:%M:%S")
664
665
666
667
668
669
+ time.strptime(test_date, "%D"),
670
+ time.strptime(test_date, "%m/%d/%y")
671
672
673
class Strptime12AMPMTests(unittest.TestCase):
674
"""Test a _strptime regression in '%I %p' at 12 noon (12 PM)"""
675
Lib/test/test_time.py
@@ -358,7 +358,7 @@ def test_strptime(self):
358
# Should be able to go round-trip from strftime to strptime without
359
# raising an exception.
360
tt = time.gmtime(self.t)
361
- 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',
362
'j', 'm', 'M', 'p', 'S', 'T',
363
'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'):
364
format = '%' + directive
@@ -379,7 +379,7 @@ def test_strptime_bytes(self):
379
380
381
382
- time.strptime('', '%D')
+ time.strptime('', '%!')
383
384
385
Misc/NEWS.d/next/Library/2026-02-14-14-56-44.gh-issue-140715.AbSheM.rst
@@ -0,0 +1 @@
1
+Add ``'%D'`` support to :meth:`~datetime.datetime.strptime`.
0 commit comments