Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions Doc/library/datetime.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2570,8 +2570,10 @@ requires, and these work on all supported platforms.
| ``%M`` | Minute as a zero-padded | 00, 01, ..., 59 | \(9) |
| | decimal number. | | |
+-----------+--------------------------------+------------------------+-------+
| ``%n`` | The newline character | ``\n`` | \(0) |
| | (``'\n'``). | | |
| ``%n`` | The newline character | ``\n`` | |
| | (``'\n'``). For | | |
| | :meth:`!strptime`, arbitrary | | |
| | whitespace. | | |
+-----------+--------------------------------+------------------------+-------+
| ``%p`` | Locale's equivalent of either || AM, PM (en_US); | \(1), |
| | AM or PM. || am, pm (de_DE) | \(3) |
Expand All @@ -2584,8 +2586,9 @@ requires, and these work on all supported platforms.
| ``%S`` | Second as a zero-padded | 00, 01, ..., 59 | \(4), |
| | decimal number. | | \(9) |
+-----------+--------------------------------+------------------------+-------+
| ``%t`` | The tab character | ``\t`` | \(0) |
| | (``'\t'``). | | |
| ``%t`` | The tab character (``'\t'``). | ``\t`` | |
| | For :meth:`!strptime`, | | |
| | arbitrary whitespace. | | |
+-----------+--------------------------------+------------------------+-------+
| ``%T`` | ISO 8601 time format, | 10:01:59 | |
| | equivalent to ``%H:%M:%S``. | | |
Expand Down Expand Up @@ -2676,7 +2679,8 @@ differences between platforms in handling of unsupported format specifiers.
``%:z`` was added for :meth:`~.datetime.strftime`.

.. versionadded:: 3.15
``%:z``, ``%F``, and ``%D`` were added for :meth:`~.datetime.strptime`.
``%D``, ``%F``, ``%n``, ``%t``, and ``%:z`` were added for
:meth:`~.datetime.strptime`.

Technical Detail
^^^^^^^^^^^^^^^^
Expand Down
5 changes: 4 additions & 1 deletion Lib/_strptime.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,10 @@ def __init__(self, locale_time=None):
'Z': self.__seqToRE((tz for tz_names in self.locale_time.timezone
for tz in tz_names),
'Z'),
'%': '%'}
'n': r'\s*',
't': r'\s*',
'%': '%'
}
if self.locale_time.LC_alt_digits is None:
for d in 'dmyCHIMS':
mapping['O' + d] = r'(?P<%s>\d\d|\d| \d)' % d
Expand Down
26 changes: 26 additions & 0 deletions Lib/test/datetimetester.py
Original file line number Diff line number Diff line change
Expand Up @@ -2207,6 +2207,32 @@ def test_strptime_D_format(self):
self.theclass.strptime(test_date, "%m/%d/%y")
)

def test_strptime_t_format(self):
test_year,test_month,test_day = 2026,2,20
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
test_year,test_month,test_day = 2026,2,20
year, month, day = 2026, 2, 20

Shorter names are clearer, and please follow PEP 8's whitespace guide.

whitespaces = ('',' ','\t','\r','\v','\n','\f')
for ws in (*whitespaces,''.join(whitespaces)):
with self.subTest(whitespace=ws):
self.assertEqual(
self.theclass.strptime(
f'{test_year:04d}{ws}{test_month:02d}{ws}{test_day:02d}',
"%Y%t%m%t%d"
),
self.theclass(test_year,test_month,test_day)
)

def test_strptime_n_format(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The two tests can be merged with e.g. for d in ('n', 't'): ...

test_year,test_month,test_day = 2026,2,25
whitespaces = ('',' ','\t','\r','\v','\n','\f')
for ws in (*whitespaces,''.join(whitespaces)):
with self.subTest(whitespace=ws):
self.assertEqual(
self.theclass.strptime(
f'{test_year:04d}{ws}{test_month:02d}{ws}{test_day:02d}',
"%Y%n%m%n%d"
),
self.theclass(test_year,test_month,test_day)
)


#############################################################################
# datetime tests
Expand Down
32 changes: 32 additions & 0 deletions Lib/test/test_strptime.py
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,38 @@ def test_strptime_D_format(self):
time.strptime(test_date, "%m/%d/%y")
)

def test_strptime_t_format(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same notes as above.

test_year,test_month,test_day = 2026,2,20
whitespaces = ('',' ','\t','\r','\v','\n','\f')
for ws in (*whitespaces,''.join(whitespaces)):
with self.subTest(whitespace=ws):
self.assertEqual(
time.strptime(
f'{test_year:04d}{ws}{test_month:02d}{ws}{test_day:02d}',
"%Y%t%m%t%d"
),
time.strptime(
f'{test_year:04d}-{test_month:02d}-{test_day:02d}',
"%Y-%m-%d"
)
)

def test_strptime_n_format(self):
test_year,test_month,test_day = 2026,2,20
whitespaces = ('',' ','\t','\r','\v','\n','\f')
for ws in (*whitespaces,''.join(whitespaces)):
with self.subTest(whitespace=ws):
self.assertEqual(
time.strptime(
f'{test_year:04d}{ws}{test_month:02d}{ws}{test_day:02d}',
"%Y%n%m%n%d"
),
time.strptime(
f'{test_year:04d}-{test_month:02d}-{test_day:02d}',
"%Y-%m-%d"
)
)

class Strptime12AMPMTests(unittest.TestCase):
"""Test a _strptime regression in '%I %p' at 12 noon (12 PM)"""

Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_time.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ def test_strptime(self):
# raising an exception.
tt = time.gmtime(self.t)
for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'D', 'F', 'H', 'I',
'j', 'm', 'M', 'p', 'S', 'T',
'j', 'm', 'M', 'n', 'p', 'S', 't', 'T',
'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'):
format = '%' + directive
if directive == 'd':
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add ``'%n'`` and ``'%t'`` support to :meth:`~datetime.datetime.strptime`.
Loading