【问题标题】:How do I convert a std::string to a boost::gregorian::date?如何将 std::string 转换为 boost::gregorian::date?
【发布时间】:2012-03-01 12:24:03
【问题描述】:

我正在尝试将 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”,则转换成功。

如何将“2012 年 3 月 1 日”等字符串转换为等效的 boost::gregorian::date

【问题讨论】:

    标签: c++ boost boost-date-time


    【解决方案1】:

    这似乎是在您的输入构面中使用%e 时出现的问题。

    Boost.Gregorian documentation 指定:

    %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;
    }    
    

    祝你好运,

    【讨论】:

      猜你喜欢
      • 2016-06-25
      • 1970-01-01
      • 1970-01-01
      • 2015-09-03
      • 2015-09-18
      • 1970-01-01
      • 1970-01-01
      • 2016-10-25
      • 1970-01-01
      相关资源
      最近更新 更多