Question

In my attempts to make libc++ and its tests work on Windows, I have come to a problem I can't seem to wrap my head around. The following code is taken from libc++ test code, and passes on Mac (aand probably FreeBSD as well), but not with MinGW-w64 nor MSVC 2010 SP1.

#include <iomanip>
#include <iostream>
#include <cassert>

template <class CharT>
struct testbuf
    : public std::basic_streambuf<CharT>
{
    typedef std::basic_string<CharT> string_type;
    typedef std::basic_streambuf<CharT> base;
private:
    string_type str_;
public:

    testbuf() {}
    testbuf(const string_type& str)
        : str_(str)
    {
        base::setg(const_cast<CharT*>(str_.data()),
                   const_cast<CharT*>(str_.data()),
                   const_cast<CharT*>(str_.data()) + str_.size());
    }
};
#if _WIN32
#define LOCALE_en_US_UTF_8 "English_USA.1252"
#else
#define LOCALE_en_US_UTF_8 "en_US.UTF-8"
#endif
int main()
{
    testbuf<char> sb("  Sat Dec 31 23:55:59 2061");
    std::istream is(&sb);
    is.imbue(std::locale(LOCALE_en_US_UTF_8));
    std::tm t = {0};
    is >> std::get_time(&t, "%c");
    std::cout << t.tm_sec << "\n";
    std::cout << t.tm_min << "\n";
    std::cout << t.tm_hour << "\n";
    std::cout << t.tm_mday << "\n";
    std::cout << t.tm_mon << "\n";
    std::cout << t.tm_year << "\n";
    std::cout << t.tm_wday << "\n";
    assert(t.tm_sec == 59);
    assert(t.tm_min == 55);
    assert(t.tm_hour == 23);
    assert(t.tm_mday == 31);
    assert(t.tm_mon == 11);
    assert(t.tm_year == 161);
    assert(t.tm_wday == 6);
}

The test passes for Mac/FreeBSD, but the different element are all 0 for Windows. This is true for MinGW-w64+libc++ and MSVC10+Microsoft's STL.

Is this just crappy locale support in Windows or is there a wrong implementation-dependent assumption (input format) at play here I can fix or work around?

Était-ce utile?

La solution 2

The problem exposed here is not - Wrong locale names - Wrong std::tm values

But lies exactly in the fact that the %c format specifier does not do what's expected here on Windows. This is easy to fix, by specifying the format in full. In this case, what I used was:

"%a %b %d %H" ":" "%M" ":" "%S %Y"

It still has problems with the %Y part (tm_year is still zero)...

Autres conseils

I'm not convinced you have the right locale string. They seem to be really badly documented, although there's what looks like a good list here.

Perhaps "american_us.1252"? (These strings are all implementation-defined, of course.)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top