C++ - Convert AM/PM time string to posix time ptime

时间:2022-08-28 16:22:33

I'm trying to convert a time string to boost::posix_time::ptime object, but the conversion is not working.This is the function thats being used.

我正在尝试将时间字符串转换为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();
}

With a input time string of 2016-Feb-29 2:00:00 AM, this function is returning Thu Dec 3 04:00:54 287564 which is obviously not correct. How can i get the correct date time from that input ? In this case the correct date time should be 2016-02-29 02:00:00

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

The time_input_facet thats being used in this function for the required conversion is "%Y-%b-%d %H:%M:%S %p"

在此函数中用于所需转换的time_input_facet为“%Y-%b-%d%H:%M:%S%p”

1 个解决方案

#1


3  

The documentation says:

文件说:

C++ - Convert AM/PM time string to posix time ptime

The exclamation mark means:

感叹号表示:

The following tables list the all the flags available for both date_time IO as well as strftime. Format flags marked with a single asterisk (*) have a behavior unique to date_time. Those flags marked with an exclamation point (!) are not usable for input (at this time). The flags marked with a hash sign (#) are implemented by system locale and are known to be missing on some platforms. The first table is for dates, and the second table is for times.

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

So you'll have to manually parse the am/pm part if you must support this using just Boost Datetime

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

Maybe you can look at Boost Locale for this task: http://www.boost.org/doc/libs/1_49_0/libs/locale/doc/html/formatting_and_parsing.html

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

This works for me:

这对我有用:

#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";
}

Prints

打印

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

#1


3  

The documentation says:

文件说:

C++ - Convert AM/PM time string to posix time ptime

The exclamation mark means:

感叹号表示:

The following tables list the all the flags available for both date_time IO as well as strftime. Format flags marked with a single asterisk (*) have a behavior unique to date_time. Those flags marked with an exclamation point (!) are not usable for input (at this time). The flags marked with a hash sign (#) are implemented by system locale and are known to be missing on some platforms. The first table is for dates, and the second table is for times.

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

So you'll have to manually parse the am/pm part if you must support this using just Boost Datetime

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

Maybe you can look at Boost Locale for this task: http://www.boost.org/doc/libs/1_49_0/libs/locale/doc/html/formatting_and_parsing.html

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

This works for me:

这对我有用:

#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";
}

Prints

打印

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