用g ++和clang ++打破std :: get_time吗?

时间:2016-05-31 18:21:38

标签: c++ c++11 time c++14

我今天正在使用一些时间函数,并注意到使用%r(或%p)的标准转换似乎不适用于通过{+ 1}}在g ++或clang ++上的输入。有关g ++和clang ++,请参阅this live code version 似乎在Windows下使用VC ++正常工作(请参阅此closely related question)。另请注意,无论是否包含std::get_time()行,效果都相同。如果重要的话,我的Linux机器上的语言环境设置为imbue

"en_US.UTF-8"

2 个答案:

答案 0 :(得分:10)

正如评论者指出的那样,这实际上是{% for order in orders %} {{ order.order_number }} {% endfor %}} 中的一个错误(遗漏)。已提交bug report

答案 1 :(得分:0)

坏消息是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';
    }

这是输出:

Conversion failed
1900-01-00

一个小小的评论:在尝试进行任何处理之前,强烈建议将std::tm对象清零。

更新:这是一种依靠UNIX函数strptime的变通方法(请注意,这不是C或C ++标准函数!)。我展示了带有ISO8601日期解析的代码示例。

首先,让我们检测GNU stdlibc++库并拉入<time.h>标头。 (在某些平台上,标题可能是<sys/time.h>):

#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
// ........