2012-03-01 41 views
8

我嘗試轉換std::stringboost::gregorian::date這樣的:如何將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

回答

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 

看來因此,這是加速實施的限制(或者至少,事實上,它依賴於一個特定的區域設置解析%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; 
}  

祝你好運,

相關問題