[Bug libstdc++/126364] New: chrono::from_stream %T and %R short circuit on out of range values even when it doesn't fail the parse

rs2740 at gmail dot com via Gcc-bugs <[email protected]>
Newsgroups gmane.comp.gcc.bugs
Message-ID <[email protected]/bugzilla/>
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.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.