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.

Reply via email to