如何将std :: string转换为boost :: gregorian :: date?

时间:2012-03-01 12:24:03

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

我正在尝试将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'

但如果字符串包含“2012年3月1日”,则转换成功。

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

1 个答案:

答案 0 :(得分:10)

在输入方面使用%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):当%e0时,解析失败了输入字符串中的第一项,并使用空格而不是前导std::noskipws

我(盲目)猜测问题来自stringstream倾向于跳过空格。我试图找到#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; } 的解决方案,然而,找不到有用的东西。

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

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

{{1}}
祝你好运,