std :: get_time и другие функции локали не работают правильно в Windows - PullRequest
0 голосов
/ 02 октября 2011

В моих попытках заставить libc ++ и его тесты работать на Windows я столкнулся с проблемой, которую, похоже, не могу обернуться.Следующий код взят из тестового кода libc ++ и проходит на Mac (и, вероятно, также на FreeBSD), но не с MinGW-w64 или 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);
}

Тест проходит для Mac / FreeBSD,но другой элемент - все 0 для Windows.Это верно для MinGW-w64 + libc ++ и MSVC10 + Microsoft STL.

Является ли это просто дрянной поддержкой локали в Windows или есть неверное зависящее от реализации предположение (формат ввода) при игре, которое я могу исправить или работатьвокруг

Ответы [ 2 ]

0 голосов
/ 03 октября 2011

Проблема здесь не - Неправильные названия локалей - Неправильно std::tm значения

Но заключается именно в том, что спецификатор формата %c не выполняет то, что ожидается здесь, в Windows. Это легко исправить, указав формат полностью. В данном случае я использовал:

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

У него все еще есть проблемы с частью %Y (tm_year по-прежнему равен нулю) ...

0 голосов
/ 02 октября 2011

Я не уверен, что у вас есть правильная строка локали. Они кажутся действительно плохо документированными, хотя здесь есть что-то вроде хорошего списка .

Возможно, "american_us.1252"? (Конечно, все эти строки определяются реализацией.)

...