Разбор строки для увеличения ::posix_time::ptime с миллисекундами

#c #boost

#c #повышение

Вопрос:

У меня есть набор функций, которые позволяют мне преобразовывать ptime в строку и string в ptime в соответствии с определенным форматом. Это работает хорошо, пока мне не понадобится использовать модификатор миллисекунды (%f).

Преобразование в строку работает нормально :

 std::string strFormat = "%Y-%m-%d %H:%M:%S.%f";
ptime now = microsec_clock::universal_time();
auto str = ToString(strFormat, now);
  

Будет выведено: 2020-08-26 12:27:54.938943

Но наоборот :

 auto pt = FromString(strFormat, str);
std::cout << to_simple_string(pt) << std::endl;
  

Выведет: не-дата-время

FromString Функция использует time_input_facet :

 boost::posix_time::ptime ptime;
boost::posix_time::time_input_facet* infacet = new boost::posix_time::time_input_facet(informat.c_str());

std::stringstream ss;
ss.imbue(std::locale(ss.getloc(), infacet));

ss.str(time);
ss >> ptime;

return ptime;
  

Как вы можете видеть Live On Coliru, удаление модификатора %f работает нормально.

Чего мне не хватает? Я безуспешно пробовал другой формат. Использование boost 1.70

Редактировать : Как указано @sugar в комментариях , использование %F вместо %f, похоже, работает в обоих направлениях. %f просто не следует использовать?

Комментарии:

1. Похоже, что документы boost неверны, а %f спецификатор недействителен. используйте %F вместо этого.

2. Действительно, использование %Y-%m-%d %H:%M:%S%F Работает в обоих направлениях. Но кажется странным, что %f работает в одну сторону, а не в другую

3. Только что нашел проблему по этой проблеме: github.com/boostorg/date_time/issues/102 %f действительно несовместимо между time_facet и time_input_facet

Ответ №1:

Оказывается, это ошибка в библиотеке Boost date_time (проблема)

Чтобы обойти это, я просто заменяю все вхождения «.%f» на «%F» :

 boost::posix_time::ptime FromString(std::string informat, std::string time)
            {
                boost::replace_all(informat, ".%f", "%F"); // Get around #102
                boost::posix_time::ptime ptime;
                boost::posix_time::time_input_facet* infacet = new boost::posix_time::time_input_facet(informat.c_str());

                std::stringstream ss;
                ss.imbue(std::locale(ss.getloc(), infacet));

                ss.str(time);
                ss >> ptime;
    
                return ptime;
            }