Previously, `datetime.strptime` would match `'z'` with the format string `'%z'` (for UTC offsets), throwing an `IndexError` by erroneously trying to parse `'z'` as a timestamp. As a special case, `'%z'` matches the string `'Z'` which is equivalent to the offset `'+00:00'`, however this behavior is not defined for lowercase `'z'`.
This change ensures a `ValueError` is thrown when encountering the original example, as follows:
```
>>> from datetime import datetime
>>> datetime.strptime('z', '%z')
ValueError: time data 'z' does not match format '%z'
```
Automerge-Triggered-By: GH:pganssle
(cherry picked from commit
04f6fbb6969e9860783b9ab4dc24b6fe3c6dab8d)
Co-authored-by: Noor Michael <nsmichael31@gmail.com>
Co-authored-by: Noor Michael <nsmichael31@gmail.com>
#XXX: Does 'Y' need to worry about having less or more than
# 4 digits?
'Y': r"(?P<Y>\d\d\d\d)",
- 'z': r"(?P<z>[+-]\d\d:?[0-5]\d(:?[0-5]\d(\.\d{1,6})?)?|Z)",
+ 'z': r"(?P<z>[+-]\d\d:?[0-5]\d(:?[0-5]\d(\.\d{1,6})?)?|(?-i:Z))",
'A': self.__seqToRE(self.locale_time.f_weekday, 'A'),
'a': self.__seqToRE(self.locale_time.a_weekday, 'a'),
'B': self.__seqToRE(self.locale_time.f_month[1:], 'B'),
with self.assertRaises(ValueError): strptime("-2400", "%z")
with self.assertRaises(ValueError): strptime("-000", "%z")
+ with self.assertRaises(ValueError): strptime("z", "%z")
def test_strptime_single_digit(self):
# bpo-34903: Check that single digit dates and times are allowed.
--- /dev/null
+:meth:`datetime.datetime.strptime` now raises ``ValueError`` instead of
+``IndexError`` when matching ``'z'`` with the ``%z`` format specifier.