2017-07-28 23 views
2

我想解析日期字符串与std::get_time(),但它似乎代码在VC++ 2015工作,但不工作在gcc 6.3和铛4.0。这里是MCVE:std :: get_time()在gcc 6.3和铿锵4.0不适用于完整的月份名称

#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和4.0铿锵(我用的ideone.comColiru编译器)的结果 - 既没有C++ 14米的标志:

parse failed 
0 
1 
0 
0 
0 

它的工作,当我使用月份的缩写,如二月,八月等

我试过在stringstreamen_US,en_GB + UTF-8版本)上设置不同的语言环境,但它们没有任何区别或导致运行时错误。我试过改变分隔符,但也没有区别。

我在CPP Reference阅读%B在std::get_time()

解析月份名称,要么全或缩写,例如十月

这是一个bug在GCC和铛或者编译器,相反,什么是上面写的,免费办理只缩写名称取决于执行/缺少的功能?标准对此有何评论?这两个编译器在这里表现出相同的行为是巧合吗?

+1

libstdC++的错误。 [与clang -stdlib = libC++一起使用。](http://coliru.stacked-crooked.com/a/3108a8e1c8921d9a) – cpplearner

+1

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78714 – cpplearner

+0

谢谢。如果您将它作为答案发布,我会接受它。 – KjMag

回答

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>