8

我正在尝试将 a 转换为std::string这样的boost::gregorian::date

using namespace boost::gregorian;

std::string str = "1 Mar 2012";
std::stringstream ss(str);
date_input_facet *df = new date_input_facet("%e %b %Y");
ss.imbue(std::locale(ss.getloc(), df));
date d;

ss >> d;  //conversion fails to not-a-date-time

std::cout << "'" << d << "'" << std::endl;  //'not-a-date-time'

但如果字符串包含“01 Mar 2012”,则转换成功。

如何将“1 Mar 2012”之类的字符串转换为等效字符串boost::gregorian::date

4

1 回答 1

10

这似乎是%e在您的输入方面使用的问题。

Boost.Gregorian文档指定:

%d 月中的一天,十进制 01 到 31

%e # 和 %d 一样,将月份中的日期作为十进制数,但前导零被替换为空格

问题是,如果您查看文档的顶部,您会注意到以下警告:

标有井号 (#) 的标志由系统语言环境实现,并且已知在某些平台上缺失

我尝试过以下案例:

input_string = " 1"
date_format = "%e"
result = failed

input_string = "01"
date_format = "%e"
result = success

input_string = "2000 Mar 1"
date_format = "%Y %b %e"
result = failed

input_string = "2000 Mar  1"
date_format = "%Y %b %e"
result = success

input_string = "2000 Mar 01"
date_format = "%Y %b %e"
result = success

因此,这似乎是 Boost 实现的一个限制(或者至少,它依赖于特定语言环境来解析 的事实%e):当%e是输入字符串中的第一项并且使用空格时,解析失败而不是领先的0.

我的(盲目的)猜测是这个问题来自 stringstream 跳过空格的倾向。我试图找到一个解决方案std::noskipws,但是,找不到有用的东西。

作为一种解决方法,我建议添加前导零,或者如果可能,使用不同的日期格式。

另一种解决方法是手动添加空格,并颠倒字符串中“单词”的顺序。我已经完成了这样的工作解决方案:

#include "boost/date_time/gregorian/gregorian.hpp"
#include <iostream>
#include <string>

int main(void) {
    using namespace boost::gregorian;

    std::string input_date("1 Mar 2000");

    { // local scope to remove temporary variables as soon as possible
        std::stringstream tmp_ss(input_date);
        std::string tmp;
        input_date.clear(); // empty the initial string
        while (tmp_ss >> tmp) {
            input_date.insert(0, tmp); // insert word at beginning of string
            if(tmp.size() == 1) // if word is one char long, add extra space
                input_date.insert(0, " ");
            input_date.insert(0, " "); // add space to separate words
        }
    }

    std::stringstream ss(input_date);

    // The order of the date is reversed.
    date_input_facet *df = new date_input_facet("%Y %b %e");
    ss.imbue(std::locale(ss.getloc(), df));
    
    date d;  //conversion works

    ss >> d;

    std::cout << "'" << d << "'" << std::endl; // ouputs date correctly.

    return 0;
}    

祝你好运,

于 2012-03-01T14:44:25.860 回答