c++localestringstreamc++-chrono

Why can't chrono::parse parse a POSIX date and time string?


I'm trying to use the <chrono> library to parse a POSIX date and time string, no matter what the global locale is, based on this code:

#include <iostream>
#include <locale>
#include <sstream>
#include <string>
#include <chrono>

using namespace std;

void printPosixDateString(string const &str) {
    istringstream stringStream{};
    stringStream.str(str);
    
    locale cLocale{"C"};//locale of C/POSIX language
    stringStream.imbue(cLocale);

    chrono::sys_seconds timeHolder{};//default value is unix time

    stringStream >> chrono::parse("%c", timeHolder);

    if(stringStream.fail()) {
        cout << "Error while parsing date string : " << stringStream.str() << endl;
    }
    else {
        cout << timeHolder;//should print the date object
    }
}

int main(int argc, char **argv) {
    locale french("fr_FR.UTF8");
    locale::global(french);
    cout.imbue(french);
    printPosixDateString("Fri Jul 5 14:58:21 2019");//must work no matter the global locale

    return 0;
}

The problem is that it always print the "Error while parsing date string: Fri Jul 5 14:58:21 2019" message.

Do you please have any explanations for this ?

I am on Arch Linux, Kernel: Linux 6.10.7-arch1-1, on a typical x86-64 computer. I use g++ 14.2.1, tried with C++20 and C++23 (which gave the same outputs) and build my file like this: g++ -std=c++20 -Wall -o main main.cpp

I hand-wrote the date string, in case I would have missed an invisible bizzare character.

I don't want to write the format myself, as I want to be able to use the "%c" locale datetime format, so that I can easily update this code to apply it to other locales.

I was expecting this output: 2019-07-5 14:58:21, but only got Error while parsing date string: Fri Jul 5 14:58:21 2019 for every of my tries.


Solution

  • This looks like it could be a gcc bug to me. I recommend a bug report. I note that your code works if you change "%c" to "%a %b %e %T %Y" which is what %c should expand to for the "C" locale.