gh-140715: Add %F format code support to strptime() (GH-140647)

Also: add tests for the `%T` format code

Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com>
This commit is contained in:
Jason Yalim, PhD 2026-02-09 05:24:15 -07:00 committed by GitHub
parent aa6ed802f2
commit d99f3fc474
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 35 additions and 5 deletions

View file

@ -2540,7 +2540,7 @@ requires, and these work on all supported platforms.
| ``%e`` | The day of the month as a | ␣1, ␣2, ..., 31 | |
| | space-padded decimal number. | | |
+-----------+--------------------------------+------------------------+-------+
| ``%F`` | Equivalent to ``%Y-%m-%d``, | 2025-10-11, | \(0) |
| ``%F`` | Equivalent to ``%Y-%m-%d``, | 2025-10-11, | |
| | the ISO 8601 format. | 1001-12-30 | |
+-----------+--------------------------------+------------------------+-------+
| ``%g`` | Last 2 digits of ISO 8601 year | 00, 01, ..., 99 | \(0) |
@ -2673,10 +2673,10 @@ differences between platforms in handling of unsupported format specifiers.
``%G``, ``%u`` and ``%V`` were added.
.. versionadded:: 3.12
``%:z`` was added for :meth:`~.datetime.strftime`
``%:z`` was added for :meth:`~.datetime.strftime`.
.. versionadded:: 3.15
``%:z`` was added for :meth:`~.datetime.strptime`
``%:z`` and ``%F`` were added for :meth:`~.datetime.strptime`.
Technical Detail
^^^^^^^^^^^^^^^^

View file

@ -418,6 +418,7 @@ def __init__(self, locale_time=None):
mapping['W'] = mapping['U'].replace('U', 'W')
base.__init__(mapping)
base.__setitem__('F', self.pattern('%Y-%m-%d'))
base.__setitem__('T', self.pattern('%H:%M:%S'))
base.__setitem__('R', self.pattern('%H:%M'))
base.__setitem__('r', self.pattern(self.locale_time.LC_time_ampm))

View file

@ -2193,6 +2193,13 @@ def test_fromisocalendar_type_errors(self):
with self.assertRaises(TypeError):
self.theclass.fromisocalendar(*isocal)
def test_strptime_F_format(self):
test_date = "2025-10-26"
self.assertEqual(
self.theclass.strptime(test_date, "%F"),
self.theclass.strptime(test_date, "%Y-%m-%d")
)
#############################################################################
# datetime tests
@ -3780,6 +3787,13 @@ def test_repr_subclass(self):
td = SubclassDatetime(2010, 10, 2, second=3)
self.assertEqual(repr(td), "SubclassDatetime(2010, 10, 2, 0, 0, 3)")
def test_strptime_T_format(self):
test_time = "15:00:00"
self.assertEqual(
self.theclass.strptime(test_time, "%T"),
self.theclass.strptime(test_time, "%H:%M:%S")
)
class TestSubclassDateTime(TestDateTime):
theclass = SubclassDatetime

View file

@ -649,6 +649,20 @@ def test_mar1_comes_after_feb29_even_when_omitting_the_year(self):
time.strptime("Feb 29", "%b %d"),
time.strptime("Mar 1", "%b %d"))
def test_strptime_F_format(self):
test_date = "2025-10-26"
self.assertEqual(
time.strptime(test_date, "%F"),
time.strptime(test_date, "%Y-%m-%d")
)
def test_strptime_T_format(self):
test_time = "15:00:00"
self.assertEqual(
time.strptime(test_time, "%T"),
time.strptime(test_time, "%H:%M:%S")
)
class Strptime12AMPMTests(unittest.TestCase):
"""Test a _strptime regression in '%I %p' at 12 noon (12 PM)"""

View file

@ -358,8 +358,8 @@ def test_strptime(self):
# 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', 'H', 'I',
'j', 'm', 'M', 'p', 'S',
for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'F', 'H', 'I',
'j', 'm', 'M', 'p', 'S', 'T',
'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'):
format = '%' + directive
if directive == 'd':

View file

@ -0,0 +1 @@
Add ``'%F'`` support to :meth:`~datetime.datetime.strptime`.