提升日期解析29FEB

时间:2015-12-19 08:25:09

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

日期时间解析存在一些问题,我不知道有很好的解决方法。

请考虑以下代码:

#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年是默认的而不是任何闰年,无论如何我需要一些不错的解决方法,任何想法?

1 个答案:

答案 0 :(得分: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时间。甚至可以使用哪个日历模型。