summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Doc/library/datetime.rst35
-rw-r--r--Lib/test/datetimetester.py35
-rw-r--r--Misc/NEWS.d/next/Documentation/2019-06-17-09-36-46.bpo-34903.r_wGRc.rst1
3 files changed, 56 insertions, 15 deletions
diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst
index fb41aeeb5b..c935e35265 100644
--- a/Doc/library/datetime.rst
+++ b/Doc/library/datetime.rst
@@ -2093,7 +2093,7 @@ format codes.
| | where 0 is Sunday and 6 is | | |
| | Saturday. | | |
+-----------+--------------------------------+------------------------+-------+
-| ``%d`` | Day of the month as a | 01, 02, ..., 31 | |
+| ``%d`` | Day of the month as a | 01, 02, ..., 31 | \(9) |
| | zero-padded decimal number. | | |
+-----------+--------------------------------+------------------------+-------+
| ``%b`` | Month as locale's abbreviated || Jan, Feb, ..., Dec | \(1) |
@@ -2106,29 +2106,29 @@ format codes.
| | || Januar, Februar, ..., | |
| | | Dezember (de_DE) | |
+-----------+--------------------------------+------------------------+-------+
-| ``%m`` | Month as a zero-padded | 01, 02, ..., 12 | |
+| ``%m`` | Month as a zero-padded | 01, 02, ..., 12 | \(9) |
| | decimal number. | | |
+-----------+--------------------------------+------------------------+-------+
-| ``%y`` | Year without century as a | 00, 01, ..., 99 | |
+| ``%y`` | Year without century as a | 00, 01, ..., 99 | \(9) |
| | zero-padded decimal number. | | |
+-----------+--------------------------------+------------------------+-------+
| ``%Y`` | Year with century as a decimal | 0001, 0002, ..., 2013, | \(2) |
| | number. | 2014, ..., 9998, 9999 | |
+-----------+--------------------------------+------------------------+-------+
-| ``%H`` | Hour (24-hour clock) as a | 00, 01, ..., 23 | |
+| ``%H`` | Hour (24-hour clock) as a | 00, 01, ..., 23 | \(9) |
| | zero-padded decimal number. | | |
+-----------+--------------------------------+------------------------+-------+
-| ``%I`` | Hour (12-hour clock) as a | 01, 02, ..., 12 | |
+| ``%I`` | Hour (12-hour clock) as a | 01, 02, ..., 12 | \(9) |
| | zero-padded decimal number. | | |
+-----------+--------------------------------+------------------------+-------+
| ``%p`` | Locale's equivalent of either || AM, PM (en_US); | \(1), |
| | AM or PM. || am, pm (de_DE) | \(3) |
+-----------+--------------------------------+------------------------+-------+
-| ``%M`` | Minute as a zero-padded | 00, 01, ..., 59 | |
+| ``%M`` | Minute as a zero-padded | 00, 01, ..., 59 | \(9) |
| | decimal number. | | |
+-----------+--------------------------------+------------------------+-------+
-| ``%S`` | Second as a zero-padded | 00, 01, ..., 59 | \(4) |
-| | decimal number. | | |
+| ``%S`` | Second as a zero-padded | 00, 01, ..., 59 | \(4), |
+| | decimal number. | | \(9) |
+-----------+--------------------------------+------------------------+-------+
| ``%f`` | Microsecond as a decimal | 000000, 000001, ..., | \(5) |
| | number, zero-padded on the | 999999 | |
@@ -2142,19 +2142,19 @@ format codes.
| ``%Z`` | Time zone name (empty string | (empty), UTC, EST, CST | |
| | if the object is naive). | | |
+-----------+--------------------------------+------------------------+-------+
-| ``%j`` | Day of the year as a | 001, 002, ..., 366 | |
+| ``%j`` | Day of the year as a | 001, 002, ..., 366 | \(9) |
| | zero-padded decimal number. | | |
+-----------+--------------------------------+------------------------+-------+
-| ``%U`` | Week number of the year | 00, 01, ..., 53 | \(7) |
-| | (Sunday as the first day of | | |
+| ``%U`` | Week number of the year | 00, 01, ..., 53 | \(7), |
+| | (Sunday as the first day of | | \(9) |
| | the week) as a zero padded | | |
| | decimal number. All days in a | | |
| | new year preceding the first | | |
| | Sunday are considered to be in | | |
| | week 0. | | |
+-----------+--------------------------------+------------------------+-------+
-| ``%W`` | Week number of the year | 00, 01, ..., 53 | \(7) |
-| | (Monday as the first day of | | |
+| ``%W`` | Week number of the year | 00, 01, ..., 53 | \(7), |
+| | (Monday as the first day of | | \(9) |
| | the week) as a decimal number. | | |
| | All days in a new year | | |
| | preceding the first Monday | | |
@@ -2194,8 +2194,8 @@ incomplete or ambiguous ISO 8601 directives will raise a :exc:`ValueError`.
| ``%u`` | ISO 8601 weekday as a decimal | 1, 2, ..., 7 | |
| | number where 1 is Monday. | | |
+-----------+--------------------------------+------------------------+-------+
-| ``%V`` | ISO 8601 week as a decimal | 01, 02, ..., 53 | \(8) |
-| | number with Monday as | | |
+| ``%V`` | ISO 8601 week as a decimal | 01, 02, ..., 53 | \(8), |
+| | number with Monday as | | \(9) |
| | the first day of the week. | | |
| | Week 01 is the week containing | | |
| | Jan 4. | | |
@@ -2291,6 +2291,11 @@ Notes:
:meth:`strptime` format string. Also note that ``%G`` and ``%Y`` are not
interchangeable.
+(9)
+ When used with the :meth:`strptime` method, the leading zero is optional
+ for formats ``%d``, ``%m``, ``%H``, ``%I``, ``%M``, ``%S``, ``%J``, ``%U``,
+ ``%W``, and ``%V``. Format ``%y`` does require a leading zero.
+
.. rubric:: Footnotes
.. [#] If, that is, we ignore the effects of Relativity
diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py
index 239a0b5ac8..53de065877 100644
--- a/Lib/test/datetimetester.py
+++ b/Lib/test/datetimetester.py
@@ -2501,6 +2501,7 @@ class TestDateTime(TestDate):
self.assertEqual(expected, got)
strptime = self.theclass.strptime
+
self.assertEqual(strptime("+0002", "%z").utcoffset(), 2 * MINUTE)
self.assertEqual(strptime("-0002", "%z").utcoffset(), -2 * MINUTE)
self.assertEqual(
@@ -2535,6 +2536,40 @@ class TestDateTime(TestDate):
with self.assertRaises(ValueError): strptime("-2400", "%z")
with self.assertRaises(ValueError): strptime("-000", "%z")
+ def test_strptime_single_digit(self):
+ # bpo-34903: Check that single digit dates and times are allowed.
+
+ strptime = self.theclass.strptime
+
+ with self.assertRaises(ValueError):
+ # %y does require two digits.
+ newdate = strptime('01/02/3 04:05:06', '%d/%m/%y %H:%M:%S')
+ dt1 = self.theclass(2003, 2, 1, 4, 5, 6)
+ dt2 = self.theclass(2003, 1, 2, 4, 5, 6)
+ dt3 = self.theclass(2003, 2, 1, 0, 0, 0)
+ dt4 = self.theclass(2003, 1, 25, 0, 0, 0)
+ inputs = [
+ ('%d', '1/02/03 4:5:6', '%d/%m/%y %H:%M:%S', dt1),
+ ('%m', '01/2/03 4:5:6', '%d/%m/%y %H:%M:%S', dt1),
+ ('%H', '01/02/03 4:05:06', '%d/%m/%y %H:%M:%S', dt1),
+ ('%M', '01/02/03 04:5:06', '%d/%m/%y %H:%M:%S', dt1),
+ ('%S', '01/02/03 04:05:6', '%d/%m/%y %H:%M:%S', dt1),
+ ('%j', '2/03 04am:05:06', '%j/%y %I%p:%M:%S',dt2),
+ ('%I', '02/03 4am:05:06', '%j/%y %I%p:%M:%S',dt2),
+ ('%w', '6/04/03', '%w/%U/%y', dt3),
+ # %u requires a single digit.
+ ('%W', '6/4/2003', '%u/%W/%Y', dt3),
+ ('%V', '6/4/2003', '%u/%V/%G', dt4),
+ ]
+ for reason, string, format, target in inputs:
+ reason = 'test single digit ' + reason
+ with self.subTest(reason=reason,
+ string=string,
+ format=format,
+ target=target):
+ newdate = strptime(string, format)
+ self.assertEqual(newdate, target, msg=reason)
+
def test_more_timetuple(self):
# This tests fields beyond those tested by the TestDate.test_timetuple.
t = self.theclass(2004, 12, 31, 6, 22, 33)
diff --git a/Misc/NEWS.d/next/Documentation/2019-06-17-09-36-46.bpo-34903.r_wGRc.rst b/Misc/NEWS.d/next/Documentation/2019-06-17-09-36-46.bpo-34903.r_wGRc.rst
new file mode 100644
index 0000000000..7e277f4ec1
--- /dev/null
+++ b/Misc/NEWS.d/next/Documentation/2019-06-17-09-36-46.bpo-34903.r_wGRc.rst
@@ -0,0 +1 @@
+Documented that in :meth:`datetime.datetime.strptime()`, the leading zero in some two-digit formats is optional. Patch by Mike Gleen.