This could be the inverse of Converting from struct timespec to std::chrono::?
I am getting my time as
const std::Chrono::CRealTimeClock::time_point RealTimeClockTime = std::Chrono::CRealTimeClock::now();
and I have to convert it to a struct timespec.
Actually, I don't, if there is an altrerntive; what I have to do is get the number of seconds since the epoch and the number of nanoseconds since the last last second.
I chose struct timespec becuase
struct timespec
{
time_t tv_sec; // Seconds - >= 0
long tv_nsec; // Nanoseconds - [0, 999999999]
};
The catch is that I need to shoehorn the seconds and nonseconds into uint32_t.
I am aware theat there is a danger of loss of precision, but reckon that we don't care too much about the nanoseconds while the year 208 problem gives me cause for concern.
However, I have to bang out some code now and we can update it later if necessary. The code has to meet another manufacturer's specification and it is likely to take weeks or months to get this problem resolved and use uint64_t.
So, how can I, right now, obtain 32 bit values of second and nanosecond from std::Chrono::CRealTimeClock::now()?
CodePudding user response:
I'm going to ignore std::Chrono::CRealTimeClock::now() and just pretend you wrote std::chrono::system_clock::now(). Hopefully that will give you the tools to deal with whatever clock you actually have.
Assume:
#include <cstdint>
struct my_timespec
{
std::uint32_t tv_sec; // Seconds - >= 0
std::uint32_t tv_nsec; // Nanoseconds - [0, 999999999]
};
Now you can write:
#include <chrono>
my_timespec
now()
{
using namespace std;
using namespace std::chrono;
auto tp = system_clock::now();
auto tp_sec = time_point_cast<seconds>(tp);
nanoseconds ns = tp - tp_sec;
return {static_cast<uint32_t>(tp_sec.time_since_epoch().count()),
static_cast<uint32_t>(ns.count())};
}
Explanation:
I've used function-local using directives to reduce code verbosity and increase readability. If you prefer you can use using declarations instead to bring individual names into scope, or you can explicitly qualify everything.
The first job is to get
now()from whatever clock you're using.Next use
std::chrono::time_point_castto truncate the precision oftptosecondsprecision. One important note is thattime_point_casttruncates towards zero. So this code assumes thatnow()is after the clock's epoch and returns a non-negativetime_point. If this is not the case, then you should use C 17'sfloorinstead.flooralways truncates towards negative infinity. I chosetime_point_castoverflooronly because of the [c 14] tag on the question.The expression
tp - tp_secis astd::chrono::durationrepresenting the time duration since the last integral second. This duration is implicitly converted to have units ofnanoseconds. This implicit conversion is typically fine as all implementations ofsystem_clock::durationhave units that are eithernanosecondsor coarser (and thus implicitly convertible to)nanoseconds. If your clock tracks units ofpicoseconds(for example), then you will need aduration_cast<nanoseconds>(tp - tp_sec)here to truncatepicosecondstonanosecondsprecision.Now you have the
{seconds, nanoseconds}information in{tp_sec, ns}. It's just that they are still instd::chronotypes and notuint32_tas desired. You can extract the internal integral values with the member functions.time_since_epoch()and.count(), and thenstatic_castthose resultant integral types touint32_t. The finalstatic_castare optional as integral conversions can be made implicitly. However their use is considered good style.
