Каков наилучший способ проанализировать миллисекундное время на С++ 11

Что было бы лучше всего для strptime, когда у нас есть строка datetime с миллисекундами?

Дано:

"30/03/09 16:31:32.121"

мы не можем использовать регулярное strptime, потому что struct tm не хранит миллисекунды. Есть ли новый класс, который может достичь этого?

Ответ 1

Я бы проанализировал эти поля вручную (чтение в int и double за секунды), затем используйте days_from_civil для преобразования года/месяца/день в chrono::system_clock::time_point:

std::chrono::system_clock::time_point t(days(days_from_civil(y, m, d)));

где days:

using days = std::chrono::duration<int, std::ratio<86400>>;

Затем вы можете добавить к этому часы, минуты и секунды. Чтобы справиться с дробными секундами, вам нужно сделать небольшой танец:

double s;
your_stream >> s;  // 32.121
using namespace std::chrono;
duration<double> dsecs(s);
seconds sec = duration_cast<seconds>(dsecs);
milliseconds ms = duration_cast<milliseconds>(dsecs - sec);
t += sec + ms;

Если вы предпочитаете, используйте round здесь для вашего преобразования в миллисекундах:

milliseconds ms = round<milliseconds>(dsecs - sec);

duration_cast усекается к нулю. Существуют и другие режимы округления: пол, круглый, ceil, по этой ссылке.

Оберните все это аккуратной функцией для простого повторного использования.: -)

Вышеприведенный код подразумевает UTC. Если ваша дата/время, которое вы разыскиваете, как известно, смещается с UTC, вы можете добавить/вычесть это смещение. Все известные реализации system_clock отслеживают Unix time, что является секундой с 1970-01-01 в часовом поясе UTC.

Обновление

После написания этого ответа я разработал более общую библиотеку, которую OP, похоже, искал в то время. Он может анализировать самые разные второстепенные оценки непосредственно в std::chrono::system_clock::time_point следующим образом:

#include "date.h"
#include <iostream>
#include <sstream>

int
main()
{
    std::istringstream in{"30/03/09 16:31:32.121\n"
                          "30/03/09 16:31:32.1214"};
    std::chrono::system_clock::time_point tp;
    in >> date::parse("%d/%m/%y %T", tp);
    using namespace date;
    std::cout << tp << '\n';
    in >> date::parse(" %d/%m/%y %T", tp);
    std::cout << tp << '\n';
}

Выводится:

2009-03-30 16:31:32.121000
2009-03-30 16:31:32.121400

В этой библиотеке используются те же методы и инструменты, которые я изначально описал, но они упакованы и готовы к использованию как одна библиотека заголовков.