Skip to content

Commit 75ebbc3

Browse files
committed
Improve error message when hour is 24 and minute/second/microsecond is not 0
1 parent e8b0fd1 commit 75ebbc3

File tree

1 file changed

+28
-15
lines changed

1 file changed

+28
-15
lines changed

Modules/_datetimemodule.c

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4636,8 +4636,12 @@ time_fromisoformat(PyObject *cls, PyObject *tstr) {
46364636
return NULL;
46374637
}
46384638

4639-
if (hour == 24 && minute == 0 && second == 0 && microsecond == 0) {
4640-
hour = 0;
4639+
if (hour == 24) {
4640+
if (minute == 0 && second == 0 && microsecond == 0) {
4641+
hour = 0;
4642+
} else {
4643+
goto invalid_iso_midnight;
4644+
}
46414645
}
46424646

46434647
PyObject *t;
@@ -4651,6 +4655,10 @@ time_fromisoformat(PyObject *cls, PyObject *tstr) {
46514655
Py_DECREF(tzinfo);
46524656
return t;
46534657

4658+
invalid_iso_midnight:
4659+
PyErr_SetString(PyExc_ValueError, "minute, second, and microsecond must be 0 when hour is 24");
4660+
return NULL;
4661+
46544662
invalid_string_error:
46554663
PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", tstr);
46564664
return NULL;
@@ -5494,20 +5502,21 @@ datetime_fromisoformat(PyObject *cls, PyObject *dtstr)
54945502
goto error;
54955503
}
54965504

5497-
if (
5498-
(hour == 24 && minute == 0 && second == 0 && microsecond == 0) && // provided alternate to midnight of next day
5499-
(month <= 12 && day <= days_in_month(year, month)) // month and day component was previously valid
5500-
) {
5501-
// Calculate midnight of the next day
5502-
hour = 0;
5503-
day += 1;
5504-
if (day > days_in_month(year, month)) {
5505-
day = 1;
5506-
month += 1;
5507-
if (month > 12) {
5508-
month = 1;
5509-
year += 1;
5505+
if ((hour == 24) && (month <= 12 && day <= days_in_month(year, month))) {
5506+
if (minute == 0 && second == 0 && microsecond == 0) {
5507+
// Calculate midnight of the next day
5508+
hour = 0;
5509+
day += 1;
5510+
if (day > days_in_month(year, month)) {
5511+
day = 1;
5512+
month += 1;
5513+
if (month > 12) {
5514+
month = 1;
5515+
year += 1;
5516+
}
55105517
}
5518+
} else {
5519+
goto invalid_iso_midnight;
55115520
}
55125521
}
55135522
PyObject *dt = new_datetime_subclass_ex(year, month, day, hour, minute,
@@ -5517,6 +5526,10 @@ datetime_fromisoformat(PyObject *cls, PyObject *dtstr)
55175526
Py_DECREF(dtstr_clean);
55185527
return dt;
55195528

5529+
invalid_iso_midnight:
5530+
PyErr_SetString(PyExc_ValueError, "minute, second, and microsecond must be 0 when hour is 24");
5531+
return NULL;
5532+
55205533
invalid_string_error:
55215534
PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
55225535

0 commit comments

Comments
 (0)