2015-12-19 58 views
1

日期時間解析存在一些問題,我不知道有什麼好的解決方法。加速日期解析29FEB

考慮下面的代碼:

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

namespace dt = boost::gregorian; 

dt::date parse_date(const std::string& msg, const std::string& format) 
{ 
    std::stringstream s(msg); 
    dt::date_input_facet * f = new dt::date_input_facet(); 
    if (format.empty()) 
    { 
     f->set_iso_format(); 
    } 
    else 
    { 
     f->format(format.c_str()); 
    } 
    std::locale l(std::locale(), f); 
    s.imbue(l); 
    dt::date result; 
    s >> result; 
    return result; 
} 

int main() 
{ 
    const std::string v = "0229"; 
    auto p = parse_date(v, "%m%d"); 
    std::cout << p << std::endl; 
} 

Live example

問題是,在日期時間解析器,默認今年是1400,是不是閏年,所以沒有2月29日在今年。主要問題當然是爲什麼1400年是默認的,而不是任何閏年,無論如何,我需要一些很好的解決方法,任何想法?

回答

3

我認爲「爲什麼」的問題並不特別相關¹。這只是它的工作方式。關鍵是你知道什麼阻止你解析它。

我只是做簡單的事情,下面,或just write a tiny spirit parser (int_parser<unsigned char, 10, 2, 2> twice)和直接構建一個ptime)。

Live On Coliru

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

namespace dt = boost::gregorian; 

dt::date parse_date_mmdd(const std::string &msg) { 
    std::stringstream s("2000" + msg); 
    dt::date_input_facet *f = new dt::date_input_facet(); 
    f->format("%Y%m%d"); 

    std::locale l(std::locale(), f); 
    s.imbue(l); 
    dt::date result; 
    s >> result; 

    return result; 
} 

int main() { 
    const std::string v = "0229"; 
    auto p = parse_date_mmdd(v); 
    std::cout << p << std::endl; 
} 

打印

2000-Feb-29 

¹答案可能就中心 「存在與DayOfYear相關聯的數據類型爲」作爲DAYOFMONTH元組(沒有用處它在日期處理庫中)。所以你永遠都要決定一個上下文年。就像你總是需要決定什麼時區來解釋一個posix時間一樣,或者甚至是使用哪個日曆模型。

+1

有一個partial_date,但可悲的是它不尊重他使用的格式字符串。如果「2902」而不是「0229」可以使用,他可以使用[this](http://coliru.stacked-crooked.com/a/8c53d94f3c5e1f44)。 – llonesmiz

+1

好找,@cv_and_he。我想知道'partial_date'對於其他任務是多麼有用(有一天會看)。這裏是[X3版本](http://coliru.stacked-crooked.com/a/752c3ab1fdd5b4e3)的完整性 – sehe

+0

有趣。當然,我只想增加一年,但我不喜歡這種方式,但可能是最好的。這是非常有趣的解決方案,使用partial_date。 – ForEveR