| ``%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`, zero or | | |
+| | more whitespace. | | |
+-----------+--------------------------------+------------------------+-------+
| ``%p`` | Locale's equivalent of either || AM, PM (en_US); | \(1), |
| | AM or PM. || am, pm (de_DE) | \(3) |
| ``%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`, | | |
+| | zero or more whitespace. | | |
+-----------+--------------------------------+------------------------+-------+
| ``%T`` | ISO 8601 time format, | 10:01:59 | |
| | equivalent to ``%H:%M:%S``. | | |
``%: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
'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
self.theclass.strptime(test_date, "%m/%d/%y")
)
+ def test_strptime_n_and_t_format(self):
+ format_directives = ('%n', '%t', '%n%t', '%t%n')
+ whitespaces = ('', ' ', '\t', '\r', '\v', '\n', '\f')
+ for fd in format_directives:
+ for ws in (*whitespaces, ''.join(whitespaces)):
+ with self.subTest(format_directive=fd, whitespace=ws):
+ self.assertEqual(
+ self.theclass.strptime(
+ f"2026{ws}02{ws}03",
+ f"%Y{fd}%m{fd}%d",
+ ),
+ self.theclass(2026, 2, 3),
+ )
+
#############################################################################
# datetime tests
time.strptime(test_date, "%m/%d/%y")
)
+ def test_strptime_n_and_t_format(self):
+ format_directives = ('%n', '%t', '%n%t', '%t%n')
+ whitespaces = ('', ' ', '\t', '\r', '\v', '\n', '\f')
+ for fd in format_directives:
+ for ws in (*whitespaces, ''.join(whitespaces)):
+ with self.subTest(format_directive=fd, whitespace=ws):
+ self.assertEqual(
+ time.strptime(
+ f"2026{ws}02{ws}03",
+ f"%Y{fd}%m{fd}%d",
+ ),
+ time.strptime(
+ f'2026-02-03',
+ "%Y-%m-%d",
+ ),
+ )
+
class Strptime12AMPMTests(unittest.TestCase):
"""Test a _strptime regression in '%I %p' at 12 noon (12 PM)"""
# 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':
--- /dev/null
+Add ``%n`` and ``%t`` support to :meth:`~datetime.datetime.strptime`.