Skip to content

Commit fca4b98

Browse files
committed
tests passed
1 parent f2d1080 commit fca4b98

File tree

5 files changed

+63
-14
lines changed

5 files changed

+63
-14
lines changed

Doc/library/datetime.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2568,9 +2568,11 @@ requires, and these work on all supported platforms.
25682568
| | || Di 16 Aug 21:30:00 | |
25692569
| | | 1988 (de_DE) | |
25702570
+-----------+--------------------------------+------------------------+-------+
2571-
| ``%C`` | The year divided by 100 and | 01, 02, ..., 99 | \(0) |
2571+
| ``%C`` | The year divided by 100 and | 01, 02, ..., 99 | |
25722572
| | truncated to an integer as a | | |
25732573
| | zero-padded decimal number. | | |
2574+
| | For :meth:`!strptime`, | | |
2575+
| | zero-padding is not required. | | |
25742576
+-----------+--------------------------------+------------------------+-------+
25752577
| ``%d`` | Day of the month as a | 01, 02, ..., 31 | \(9) |
25762578
| | zero-padded decimal number. | | |

Lib/_strptime.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -371,9 +371,9 @@ def __init__(self, locale_time=None):
371371
# W is set below by using 'U'
372372
'y': r"(?P<y>\d\d)",
373373
'Y': r"(?P<Y>\d\d\d\d)",
374-
# follow C99 specification of only parsing two digits for
374+
# follow C99 specification of parsing up to two digits for
375375
# first hundred centuries
376-
'C': r"(?P<C>\d\d)",
376+
'C': r"(?P<C>\d{1,2})",
377377
# See gh-121237: "z" must support colons for backwards compatibility.
378378
'z': r"(?P<z>([+-]\d\d:?[0-5]\d(:?[0-5]\d(\.\d{1,6})?)?)|(?-i:Z))?",
379379
':z': r"(?P<colon_z>([+-]\d\d:[0-5]\d(:[0-5]\d(\.\d{1,6})?)?)|(?-i:Z))?",
@@ -617,6 +617,21 @@ def parse_int(s):
617617
year += 2000
618618
else:
619619
year += 1900
620+
elif group_key == 'C' and 'y' not in found_dict:
621+
# C99 support for century in [0,99] (years 0-9999).
622+
century = parse_int(found_dict[group_key])
623+
year = century * 100
624+
if century > 0:
625+
year = century * 100
626+
elif century == 0:
627+
# ValueError fix, since MINYEAR = 1 in Lib/_pydatetime.py
628+
year = 1
629+
else:
630+
# in line with other format directives, negative numbers
631+
# are not supported by the regular expression;
632+
# this branch will not trigger!
633+
msg = f"Negative century unsupported ({found_dict[group_key]})"
634+
raise ValueError(msg)
620635
elif group_key == 'Y':
621636
year = int(found_dict['Y'])
622637
elif group_key == 'G':
@@ -627,15 +642,6 @@ def parse_int(s):
627642
month = locale_time.f_month.index(found_dict['B'].lower())
628643
elif group_key == 'b':
629644
month = locale_time.a_month.index(found_dict['b'].lower())
630-
elif group_key == 'C' and 'y' not in found_dict:
631-
# C99 support for century in [0,99] (years 0-9999).
632-
century = parse_int(found_dict[group_key])
633-
year = century * 100
634-
if century > 0:
635-
year = century * 100
636-
else:
637-
# ValueError fix, since MINYEAR = 1 in Lib/_pydatetime.py
638-
year = 1
639645
elif group_key == 'd':
640646
day = parse_int(found_dict['d'])
641647
elif group_key == 'H':

Lib/test/datetimetester.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2221,6 +2221,26 @@ def test_strptime_n_and_t_format(self):
22212221
self.theclass(2026, 2, 3),
22222222
)
22232223

2224+
def test_strptime_C_format(self):
2225+
# verify cent. 0, zero-padding, modern cent., last supported cent.
2226+
test_centuries = ('0', '01', '20', '99')
2227+
for c in test_centuries:
2228+
expected_year = int(c) * 100 if int(c) != 0 else 1
2229+
with self.subTest(format_directive="C", century=c):
2230+
self.assertEqual(
2231+
self.theclass.strptime(c, "%C"),
2232+
self.theclass(expected_year, 1, 1)
2233+
)
2234+
2235+
def test_strptime_C_y_format(self):
2236+
# verify %y correctly augmented by century %C
2237+
test_years = ('0001', '1687', '1991', '2026')
2238+
for y in test_years:
2239+
with self.subTest(format_directive="%C%y", year=y):
2240+
self.assertEqual(
2241+
self.theclass.strptime(y, "%C%y"),
2242+
self.theclass(int(y), 1, 1)
2243+
)
22242244

22252245
#############################################################################
22262246
# datetime tests

Lib/test/test_strptime.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,27 @@ def test_strptime_n_and_t_format(self):
687687
),
688688
)
689689

690+
def test_strptime_C_format(self):
691+
# verify cent. 0, zero-padding, modern cent., last supported cent.
692+
test_centuries = ('0', '01', '20', '99')
693+
for c in test_centuries:
694+
expected_year = int(c) * 100 if int(c) != 0 else 1
695+
with self.subTest(format_directive="C", century=c):
696+
self.assertEqual(
697+
time.strptime(c, "%C"),
698+
time.strptime(f'{expected_year:04d}-01-01', '%Y-%m-%d'),
699+
)
700+
701+
def test_strptime_C_y_format(self):
702+
# verify %y correctly augmented by century %C
703+
test_years = ('0001', '1687', '1991', '2026')
704+
for year in test_years:
705+
with self.subTest(format_directive="%C%y", year=year):
706+
self.assertEqual(
707+
time.strptime(year, '%C%y'),
708+
time.strptime(f'{year}-01-01', '%Y-%m-%d'),
709+
)
710+
690711
class Strptime12AMPMTests(unittest.TestCase):
691712
"""Test a _strptime regression in '%I %p' at 12 noon (12 PM)"""
692713

Lib/test/test_time.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,8 @@ def test_strptime(self):
358358
# Should be able to go round-trip from strftime to strptime without
359359
# raising an exception.
360360
tt = time.gmtime(self.t)
361-
for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'D', 'F', 'H', 'I',
362-
'j', 'm', 'M', 'n', 'p', 'S', 't', 'T',
361+
for directive in ('a', 'A', 'b', 'B', 'c', 'C', 'd', 'D', 'F', 'H',
362+
'I', 'j', 'm', 'M', 'n', 'p', 'S', 't', 'T',
363363
'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'):
364364
format = '%' + directive
365365
if directive == 'd':

0 commit comments

Comments
 (0)