2015-07-14 4 views
8

У меня есть поток значений struct timespec. Я хотел бы преобразовать их в родное представление C++ 11, но я полностью обернулся хроно. Какое лучшее место назначения и как туда добраться из struct timespec или struct timeval, поскольку это простое преобразование, а микросекунды - достаточно хороши для этих таймингов? Я исхожу из того, что хочу быть к этому, не так ли? std :: chrono :: system_clock :: time_pointПреобразование из struct timespec в std :: chrono ::?

В этом случае timespec является временем UNIX с GPS. И да, они используют 4 байт вторые (преобразованные формы, подписанные в памяти, а затем записываются в виде знака), которые будут получать пригвождены 2038

Для справки, я буду добавлять это к считывателю C++ для gsf

ответ

20

Иногда я вижу timespec и timeval используется как длительность, а иногда я вижу, что они используются в качестве временных точек. Вы должны будете знать, какие ценности вы держите. В <chrono> эти два понятия разные.

Продолжительность - это количество времени: что-то, что вы могли бы измерить с помощью секундомера. Пример длительности составляет 2 минуты, 3 секунды, 4 часа и 16 лет.

Время - это конкретное время: 2 вечера 14 июля 2015 г. EDT, или 6 часов с момента загрузки моего компьютера. Временная точка имеет связанную с ней временную эпоху. Эпоха - это просто взаимно согласованное происхождение, с которым вы измеряете время.

Если timespec имеет продолжительность:

timespec ts = {3, 123}; // 3 seconds + 123 nanoseconds 
auto d = std::chrono::seconds{ts.seconds} 
     + std::chrono::nanoseconds{ts.nanoseconds}; 

Если ваш timespec держит момент времени, вы должны знать эпоху. Вполне вероятно, что эпоха 1970-01-01 00:00:00 UTC, пренебрегая прыжковыми секундами (это Unix time). Если это так, вы можете поместить его в std::chrono::system_clock::time_point. Этот тип не гарантированно иметь эту эпоху, но каждая реализация делает:

using namespace std::chrono; 
system_clock::time_point tp{duration_cast<system_clock::duration>(d)}; 

где d вычисляется, как описано выше.

Если у вас есть timeval, используйте microseconds, где я использовал nanoseconds.

Вы не можете портативно использовать high_resolution_clock или steady_clock time_points, потому что разные реализации имеют разные эпохи для этих типов.

Кроме того, если вы используете timeval, на практике duration_cast становится ненужным, поскольку продолжительность d неявно преобразовать во всех реализациях system_clock::duration:

using namespace std::chrono; 
system_clock::time_point tp{d}; 

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

+0

'std :: chrono :: system_clock' имеет методы удобства' from_time_t' и 'to_time_t'. Они должны обеспечить более переносимое преобразование, если мы говорим о 'time_points'. – user666412

+0

@ user666412: Да. Я помещал 'from_time_t' и' to_time_t' в C++ 11.:-) К сожалению, 'time_t' обычно является как интегральным, так и представляет секунды, тогда как' timespec' и 'timeval' представляют единицы более мелкие, чем секунды. Поэтому переход через 'to/from_time_t' означает, что вы должны урезать свою точность до секунд, а затем как-то восстановить эту точность. Между вами и мной преимущество 'to/from_time_t' заключается в том, что оно рекомендовало разработчикам использовать стандарт UnixTime для' system_clock'. :-) –

+0

Интересный факт. Спасибо, что поделились. Я просто думал о 'to/from_time_t' как переносном способе настройки эпохи, поскольку это может быть специфичным для реализации, а доли секунд могут быть добавлены так же, как и с длительностью. – user666412

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