日時をBoost.Spirit.Qiでパースしてshand::date_timeに変換

#include <iostream>
#include <shand/date_time.hpp>
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/io.hpp>

shand::date_time ParseDateTime(const std::string& s)
{
    namespace qi = boost::spirit::qi;
    namespace fusion = boost::fusion;
    using namespace shand;

    typedef fusion::vector<int, int, int, int, int, int> value_type;
    typedef qi::rule<std::string::const_iterator, value_type()> rule_type;

    const rule_type r = qi::int_ >> '-' >> qi::int_ >> '-' >> qi::int_ >> ' ' >>
                        qi::int_ >> ':' >> qi::int_ >> ':' >> qi::int_;

    std::string::const_iterator it = s.begin();
    value_type result;
    if (!qi::parse(it, s.end(), r, result)) {
        throw std::runtime_error("parse error");
    }

    return date_time(
        year(fusion::at_c<0>(result)) &
        month(fusion::at_c<1>(result)) &
        day(fusion::at_c<2>(result)) &
        hour(fusion::at_c<3>(result)) &
        minute(fusion::at_c<4>(result)) &
        second(fusion::at_c<5>(result))
        );
}

int main()
{
    shand::date_time tm = ParseDateTime("2009-3-1 15:30:12");
    std::cout << tm.format("%Y/%m/%d %H:%M") << std::endl;
}

めんどくさいめんどくさい。
んー・・・何か考えます。


追記(2011/01/06 17:19):
「YYYY/MM/DD HH:MM:SS」と「YYYY-MM-DD HH:MM:SS」両方に対応する必要がでてきたので例を追加。

#include <iostream>
#include <shand/date_time.hpp>
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/io.hpp>

shand::date_time ParseDateTime(const std::string& s)
{
    namespace qi = boost::spirit::qi;
    namespace fusion = boost::fusion;
    using namespace shand;

    typedef fusion::vector<int, int, int, int, int, int> value_type;
    typedef qi::rule<std::string::const_iterator, value_type()> rule_type;

    const rule_type r = qi::int_ >> qi::omit[qi::char_("-/")] >>
                        qi::int_ >> qi::omit[qi::char_("-/")] >>
                        qi::int_ >> ' ' >>
                        qi::int_ >> ':' >> qi::int_ >> ':' >> qi::int_;

    std::string::const_iterator it = s.begin();
    value_type result;
    if (!qi::parse(it, s.end(), r, result)) {
        throw std::runtime_error("parse error");
    }

    return date_time(
        year(fusion::at_c<0>(result)) &
        month(fusion::at_c<1>(result)) &
        day(fusion::at_c<2>(result)) &
        hour(fusion::at_c<3>(result)) &
        minute(fusion::at_c<4>(result)) &
        second(fusion::at_c<5>(result))
        );
}

int main()
{
    {
    shand::date_time tm = ParseDateTime("2009-03-01 15:30:12");
    std::cout << tm.format("%Y/%m/%d %H:%M") << std::endl;
    }
    [
    shand::date_time tm = ParseDateTime("2011/01/06 00:03:57");
    std::cout << tm.format("%Y/%m/%d %H:%M") << std::endl;
    }
}
2009/03/01 15:30:12
2011/01/06 00:03:57