这似乎是在您的输入构面中使用%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;
}
祝你好运,