C++ 是std::在g++;和叮当声++;?

C++ 是std::在g++;和叮当声++;?,c++,c++11,time,c++14,C++,C++11,Time,C++14,我今天使用了一些时间函数,注意到使用%r(或%p)的标准转换对于通过g++或clang++上的std::get_time()输入似乎不起作用。有关g++和clang++的信息,请参见。在使用VC++的Windows环境下,它似乎确实如预期的那样工作(请参见此)。还请注意,无论是否包括imbue行,效果都是相同的。我的Linux机器上的语言环境设置为“en_US.UTF-8”,如果有必要的话 #include <iostream> #include <iomanip> #i

我今天使用了一些时间函数,注意到使用
%r
(或
%p
)的标准转换对于通过g++或clang++上的
std::get_time()
输入似乎不起作用。有关g++和clang++的信息,请参见。在使用VC++的Windows环境下,它似乎确实如预期的那样工作(请参见此)。还请注意,无论是否包括
imbue
行,效果都是相同的。我的Linux机器上的语言环境设置为
“en_US.UTF-8”
,如果有必要的话

#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <ctime>

int main(){
    std::tm t{};
    std::stringstream ss{"1:23:45 PM"};
    ss.imbue(std::locale(std::cin.getloc(), 
             new std::time_get_byname<char>("en_US")));
    ss >> std::get_time(&t, "%r");
    if (ss.fail()) {
        std::cout << "Conversion failed\n" << std::put_time(&t, "%r") << '\n';
    } else {
        std::cout << std::put_time(&t, "%r") << '\n';
    }
}
#包括
#包括
#包括
#包括
#包括
int main(){
std::tmt{};
std::stringstream ss{“下午1:23:45”};
ss.imbue(std::locale(std::cin.getloc(),
新标准:时间以名字命名(“en_US”);
ss>>std::获取时间(&t,“%r”);
if(ss.fail()){

std::cout正如评论者所指出的,这实际上是
libstdc++
中的一个bug(一个遗漏)。a已经提交。

坏消息是
get_time()
比OP和评论者所想的更坏。它肯定不能与
%F
格式说明符一起工作(日期采用ISO-8601格式,例如,
“2019-01-13”
)我稍微修改了OP的代码以证明这一点。使用Ubuntu 18.04.1下的
g++
版本7.3.0编译:

#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <ctime>

int main(){
    std::tm tdate{0,0,0,0,0,0,0,0,-1}; // was t{};
    std::istringstream ins{"2019-01-13"};
    ss.imbue(std::locale(std::cin.getloc(), 
             new std::time_get_byname<char>("en_US")));
    ss >> std::get_time(&tdate, "%F");
    if (ss.fail()) {
        std::cout << "Conversion failed\n" << std::put_time(&tdate, "%F") << '\n';
    } else {
        std::cout << std::put_time(&tdate, "%F") << '\n';
    }
一个小提示:在尝试任何处理之前,最好将
std::tm
对象归零

更新:这里是一个依赖UNIX函数<代码> StrutTime/Cuff>的解决方案(注意这不是C或C++标准函数!)。 首先,让我们检测GNU

stdlibc++
库并拉入
头(在某些平台上,头可能是
):


这似乎是一个libstdc++问题。用libc++叮当一声就可以解决这个问题。@HowardHinnant:是的。我应该重新回答这个问题吗?看起来这个问题不处理
%r
%p
。如果有其他地方应该处理它们,我找不到它。
Conversion failed
1900-01-00
#include <cstddef>
#if defined(__GLIBCXX__) || defined(__GLIBCPP__)
#define GET_TIME_WORKAROUND
#include <time.h>
#endif
#ifdef GET_TIME_WORKAROUND
char *result = strptime(datestr.c_str(), "%F", &_cal);
if (result == nullptr) {
    throw std::invalid_argument{ "Date(" + datestr + "): ISO-8601 date expected" };
}
#else
// proper C++11
// ........