@@ -465,13 +465,14 @@ def _parse_isoformat_time(tstr):
465
465
466
466
hour , minute , second , microsecond = time_comps
467
467
became_next_day = False
468
+ error_from_components = False
468
469
if (hour == 24 ):
469
- if not all (time_comp == 0 for time_comp in time_comps [1 :]):
470
- raise ValueError ( "minute, second, and microsecond must be 0 when hour is 24" )
471
-
472
- hour = 0
473
- time_comps [ 0 ] = hour
474
- became_next_day = True
470
+ if all (time_comp == 0 for time_comp in time_comps [1 :]):
471
+ hour = 0
472
+ time_comps [ 0 ] = hour
473
+ became_next_day = True
474
+ else :
475
+ error_from_components = True
475
476
476
477
tzi = None
477
478
if tz_pos == len_str and tstr [- 1 ] == 'Z' :
@@ -505,7 +506,7 @@ def _parse_isoformat_time(tstr):
505
506
506
507
time_comps .append (tzi )
507
508
508
- return time_comps , became_next_day
509
+ return time_comps , became_next_day , error_from_components
509
510
510
511
# tuple[int, int, int] -> tuple[int, int, int] version of date.fromisocalendar
511
512
def _isoweek_to_gregorian (year , week , day ):
@@ -1912,11 +1913,14 @@ def fromisoformat(cls, date_string):
1912
1913
1913
1914
if tstr :
1914
1915
try :
1915
- time_components , became_next_day = _parse_isoformat_time (tstr )
1916
+ time_components , became_next_day , error_from_components = _parse_isoformat_time (tstr )
1916
1917
except ValueError :
1917
1918
raise ValueError (
1918
1919
f'Invalid isoformat string: { date_string !r} ' ) from None
1919
1920
else :
1921
+ if error_from_components :
1922
+ raise ValueError ("minute, second, and microsecond must be 0 when hour is 24" )
1923
+
1920
1924
if became_next_day :
1921
1925
year , month , day = date_components
1922
1926
# Only wrap day/month when it was previously valid
0 commit comments