2014-10-23 3 views
10

Что будет следующей лучшей вещью для strptime, когда у нас есть строка datetime с миллисекундами?Каков наилучший способ проанализировать миллисекунду даты в C++ 11

Дано:

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

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

+0

['std :: get_time'] (http://en.cppreference.com/w/cpp/io/manip/get_time) - это C++ 11, но отражает спецификацию' strptime'. Вам нужно хранить миллисекунды, или вам нужно только отображать его? –

+0

Моя цель - сохранить это время в хронологическую точку, поэтому мне нужно, чтобы он разбирался и хранился. – Nezquick

+0

С .1214 вы не запрашиваете миллисекунды, но за 1/10 миллисекунды или 100 микросекунд. –

ответ

6

Я бы разобрать эти поля вручную (чтение в междунар и дважды в течение секунд), а затем использовать 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 from here для преобразования миллисекунды:

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

duration_cast является усечение к нулю. Существуют и другие режимы округления: пол, круглый, потолок, at this link.

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

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

Update

С момента написания этого ответа я разработал more general library, что ОП, казалось, стремится в то время. Это может анализировать широкий спектр суб вторых точностей непосредственно в 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 

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

+0

вместо использования days_from_civil (еще одна внешняя библиотека) Я использовал регулярное time_t, чтобы получить часть даты. :) Я закончил с использованием google: re2, чтобы прочитать шаблон, так как я хотел что-то более общее. благодаря – Nezquick

Смежные вопросы