C ++ - 将AM / PM时间字符串转换为posix时间ptime

时间:2016-03-12 16:11:34

标签: c++ boost

我正在尝试将时间字符串转换为boost::posix_time::ptime对象,但转换不起作用。这是正在使用的函数。

std::string Parser::getFormattedDate(std::string datetime)
{
  std::stringstream date_strm, date_res;
  boost::posix_time::ptime pt;
  boost::posix_time::time_input_facet *facet = new boost::posix_time::time_input_facet( "%Y-%b-%d %H:%M:%S %p" );

  date_strm.imbue( std::locale( std::locale(), facet ));
  date_strm << datetime;
  date_strm >> pt;

  date_res << pt.date().year() << "-" << std::setw(2) << std::setfill('0') << pt.date().month().as_number()
           << "-" << std::setw(2) << std::setfill('0') << pt.date().day() << " "
           << pt.time_of_day().hours() << ":" << pt.time_of_day().minutes() << ":" << pt.time_of_day().seconds();

  return date_res.str();
}

如果输入时间字符串为2016-Feb-29 2:00:00 AM,则此函数返回Thu Dec 3 04:00:54 287564,这显然不正确。如何从输入中获得正确的日期时间?在这种情况下,正确的日期时间应为2016-02-29 02:00:00

此功能中用于所需转化的time_input_facet"%Y-%b-%d %H:%M:%S %p"

1 个答案:

答案 0 :(得分:3)

documentation说:

enter image description here

感叹号表示:

  

下表列出了date_time IO和strftime可用的所有标志。标有单个星号(*)的格式标志具有date_time独有的行为。 标有感叹号(!)的标记不能用于输入(此时) 。标有哈希符号(#)的标志由系统区域设置实现,并且已知在某些平台上缺失。第一个表用于日期,第二个表用于时间。

因此,如果必须使用Boost Datetime支持,则必须手动解析am / pm部分

也许你可以查看Boost Locale来完成这项任务:http://www.boost.org/doc/libs/1_49_0/libs/locale/doc/html/formatting_and_parsing.html

这对我有用:

#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <boost/locale.hpp>

static std::locale s_loc = boost::locale::generator{}.generate("");

std::string getFormattedDate(std::string datetime) {
    boost::posix_time::ptime pt;
    using namespace boost::locale;

    std::stringstream ss(datetime);
    ss.imbue(s_loc);

    date_time dt;
    if (ss >> as::ftime("%Y-%b-%d %I:%M:%S %p") >> dt) {
        ss.str("");
        ss.clear();
        ss << as::ftime("%Y-%m-%d %H:%M:%S") << dt;
        return ss.str();
    }

    throw std::bad_cast();
}

int main() {
    std::locale::global(s_loc);
    for (auto s : { "2016-Feb-29 02:06:22 AM", "2016-Mar-29 02:06:22 PM" })
        std::cout << s << " -> " << getFormattedDate(s) << "\n";
    std::cout << "Bye\n";
}

打印

2016-Feb-29 02:06:22 AM -> 2016-02-29 02:06:22
2016-Mar-29 02:06:22 PM -> 2016-03-29 14:06:22
Bye