Index: generic/tclClock.c ================================================================== --- generic/tclClock.c +++ generic/tclClock.c @@ -3739,12 +3739,12 @@ Tcl_SetErrorCode(opts->interp, "CLOCK", "dateTooLarge", (char *)NULL); return TCL_ERROR; } } - /* If seconds overflows the day (no validate case), increase days */ - if (yySecondOfDay >= SECONDS_PER_DAY) { + /* If seconds overflows the day (no validate and "24:00" case), increase days */ + if (yySecondOfDay >= SECONDS_PER_DAY + ((info->flags & CLF_TIME) && (yyHour == 24))) { yydate.julianDay += (yySecondOfDay / SECONDS_PER_DAY); yySecondOfDay %= SECONDS_PER_DAY; } /* Local seconds to UTC (stored in yydate.seconds) */ @@ -3884,23 +3884,23 @@ } } if (info->flags & CLF_TIME) { /* hour */ - if (yyHour < 0 || yyHour > ((yyMeridian == MER24) ? 23 : 12)) { + if (yyHour < 0 || yyHour > ((yyMeridian == MER24) ? 24 : 12)) { errMsg = "invalid time (hour)"; errCode = "hour"; goto error; } /* minutes */ - if (yyMinutes < 0 || yyMinutes > 59) { + if (yyMinutes < 0 || yyMinutes > 59 || (yyMinutes && (yyHour == 24))) { errMsg = "invalid time (minutes)"; errCode = "minutes"; goto error; } /* oldscan could return secondOfDay (parsedTime) -1 by invalid time (ex.: 25:00:00) */ - if (yySeconds < 0 || yySeconds > 59 || yySecondOfDay <= -1) { + if (yySeconds < 0 || yySeconds > 59 || yySecondOfDay <= -1 || (yySeconds && (yyHour == 24))) { errMsg = "invalid time"; errCode = "seconds"; goto error; } } Index: generic/tclDate.c ================================================================== --- generic/tclDate.c +++ generic/tclDate.c @@ -2346,13 +2346,13 @@ { switch (Meridian) { case MER24: return (Hours * 60 + Minutes) * 60 + Seconds; case MERam: - return ((Hours % 12) * 60 + Minutes) * 60 + Seconds; + return (((Hours / 24) * 24 + (Hours % 12)) * 60 + Minutes) * 60 + Seconds; case MERpm: - return (((Hours % 12) + 12) * 60 + Minutes) * 60 + Seconds; + return (((Hours / 24) * 24 + (Hours % 12) + 12) * 60 + Minutes) * 60 + Seconds; } return -1; /* Should never be reached */ } static int Index: generic/tclGetDate.y ================================================================== --- generic/tclGetDate.y +++ generic/tclGetDate.y @@ -716,13 +716,13 @@ { switch (Meridian) { case MER24: return (Hours * 60 + Minutes) * 60 + Seconds; case MERam: - return ((Hours % 12) * 60 + Minutes) * 60 + Seconds; + return (((Hours / 24) * 24 + (Hours % 12)) * 60 + Minutes) * 60 + Seconds; case MERpm: - return (((Hours % 12) + 12) * 60 + Minutes) * 60 + Seconds; + return (((Hours / 24) * 24 + (Hours % 12) + 12) * 60 + Minutes) * 60 + Seconds; } return -1; /* Should never be reached */ } static int Index: tests/clock.test ================================================================== --- tests/clock.test +++ tests/clock.test @@ -37179,17 +37179,17 @@ [clock scan 24:00:00 -base 0 -gmt 1] \ [clock scan 48:00:00 -base 0 -gmt 1] } {86399 86400 172800} } else { test clock-46.8a {regression test - invalid time (hour)} { - list [catch {clock scan 24:00:00 -base 0 -gmt 1 -format %H:%M:%S} msg] $msg \ + list [catch {clock scan 24:00:01 -base 0 -gmt 1 -format %H:%M:%S} msg] $msg \ [catch {clock scan 48:00:00 -base 0 -gmt 1 -format %H:%M:%S} msg] $msg - } {1 {unable to convert input string: invalid time (hour)} 1 {unable to convert input string: invalid time (hour)}} + } {1 {unable to convert input string: invalid time} 1 {unable to convert input string: invalid time (hour)}} test clock-46.8b {freescan: regression test - invalid time (hour)} { - list [catch {clock scan 24:00:00 -base 0 -gmt 1} msg] $msg \ + list [catch {clock scan 24:00:01 -base 0 -gmt 1} msg] $msg \ [catch {clock scan 48:00:00 -base 0 -gmt 1} msg] $msg - } {1 {unable to convert input string: invalid time (hour)} 1 {unable to convert input string: invalid time (hour)}} + } {1 {unable to convert input string: invalid time} 1 {unable to convert input string: invalid time (hour)}} } proc _invalid_test {testtz scnargs args} { global valid_mode # ensure validation works TZ independently, since the conversion @@ -38467,12 +38467,12 @@ set res {} foreach {d i} { "2012-06-29 23:59:60" "invalid time" "2012-05-30 23:59:60" "invalid time" "2012-05-30 23:60:60" "invalid time" - "2012-05-30 24:00:60" "invalid time" - "2012-05-30 24:60:00" "invalid time" + "2012-05-30 24:00:01" "invalid time" + "2012-05-30 24:10:00" "invalid time" } { # check with free scan: if {![catch { clock scan $d -gmt 1 } t] || ![string match *$i* $t]} { lappend res "free-scan \"$d\" == \"$t\", expected \"$i\"" }