我想用std::get_time()
解析日期字符串,但似乎代码适用于VC ++ 2015,但不适用于gcc 6.3和clang 4.0。这是MCVE:
#include <iostream>
#include <sstream>
#include <string>
#include <iomanip>
int main() {
std::string line = "February 4 1993 15:21";
std::tm date_1 = {};
std::stringstream ss(line);
ss >> std::get_time(&date_1, "%b %d %Y %H:%M");
if(ss.fail())
{
std::cout << "parse failed\n";
}
std::cout << date_1.tm_year << "\n";
std::cout << date_1.tm_mon << "\n";
std::cout << date_1.tm_mday << "\n";
std::cout << date_1.tm_hour << "\n";
std::cout << date_1.tm_min << "\n";
return 0;
}
这是VC ++ 2015的结果:
93
1
4
15
21
以下是gcc 6.3.2和clang 4.0的结果(我在ideone.com和Coliru上使用了编译器) - 有和没有c ++ 14标志:
parse failed
0
1
0
0
0
当我使用缩写的月份名称时,它会起作用,例如2月,8月等。
我尝试在stringstream
(en_US
,en_GB
+ UTF-8版本)上设置不同的区域设置,但它们没有任何区别或导致运行时错误。我尝试过改变分隔符,但也没有区别。
我已在CPP Reference上读到std::get_time()
中的%b:
解析月份名称,完整或缩写,例如辛
这是gcc和clang中的错误/缺失功能还是编译器,与上面的内容相反,根据实现可以自由处理缩写名称?标准对此有何看法?这两个编译器在这里表现出相同的行为是巧合吗?
答案 0 :(得分:2)
如评论中所述,这是一个libstdc ++错误。然而,没有注意到如何解决它。
使用%B
代替%b
,libstdc ++将进行解析。对于解析,%B
和%b
应具有相同的行为。但是对于格式化,%B
输出语言环境的完整月份名称,而%b
格式化缩写的月份名称。
最后,您可能对Howard Hinnant's free, open-source date-time library感兴趣,它允许您直接解析<chrono>
个时间点和持续时间:
#include "date.h"
#include <iostream>
#include <sstream>
int
main()
{
using namespace date;
using namespace std::chrono;
std::istringstream in{"February 4 1993 15:21"};
sys_time<minutes> tp;
in >> parse("%B %d %Y %H:%M", tp);
if (in.fail())
return 1;
std::cout << tp << '\n';
}
输出:
1993-02-04 15:21
在上面的示例中,sys_time<minutes>
是std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>
的类型别名。