https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126364
Bug ID: 126364
Summary: chrono::from_stream %T and %R short circuit on out of
range values even when it doesn't fail the parse
Product: gcc
Version: 16.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
Assignee: unassigned at gcc dot gnu.org
Reporter: rs2740 at gmail dot com
Target Milestone: ---
#include <chrono>
#include <iostream>
#include <sstream>
#include <string>
using namespace std::chrono;
static void probe(std::string const& input, char const* fmt) {
std::istringstream is(input);
year_month_day ymd{};
from_stream(is, fmt, ymd);
std::cout << "input=\"" << input << "\" fmt=\"" << fmt << "\" -> ";
if (is.fail()) {
std::cout << "FAIL";
}
else {
std::cout << "ok ymd=" << ymd;
}
std::cout << "\n";
}
int main() {
probe("2019-09-05T25:36:57Z", "%FT%TZ"); // hour 25 only
probe("2019-09-05T20:99:57Z", "%FT%TZ"); // minute 99 only
probe("2019-09-05T20:36:99Z", "%FT%TZ"); // second 99 only
probe("2019-09-05T25:36:57Z", "%FT%T"); // hour 25 only, no Z
probe("2019-09-05T20:99:57Z", "%FT%T"); // minute 99 only, no Z
probe("2019-09-05T20:36:99Z", "%FT%T"); // second 99 only, no Z
probe("2019-09-05 25", "%F %H"); // %H out of range alone
probe("2019-09-05 99", "%F %M"); // %M out of range alone
}
prints
input="2019-09-05T25:36:57Z" fmt="%FT%TZ" -> FAIL
input="2019-09-05T20:99:57Z" fmt="%FT%TZ" -> FAIL
input="2019-09-05T20:36:99Z" fmt="%FT%TZ" -> ok ymd=2019-09-05
input="2019-09-05T25:36:57Z" fmt="%FT%T" -> ok ymd=2019-09-05
input="2019-09-05T20:99:57Z" fmt="%FT%T" -> ok ymd=2019-09-05
input="2019-09-05T20:36:99Z" fmt="%FT%T" -> ok ymd=2019-09-05
input="2019-09-05 25" fmt="%F %H" -> ok ymd=2019-09-05
input="2019-09-05 99" fmt="%F %M" -> ok ymd=2019-09-05
It looks like what happens is that when %T (and %R) parses an out-of-range
value for the hour or minute, it stops parsing immediately (but only sets
failbit if the value is actually needed), so as a result the first two fail,
not because the parsed value is out of range, but because the Z in the format
string doesn't match against the : following the parsed hour/minute.