Initialize std::chrono::time_point variable with zero - c++

I have a variable called last_timestamp_ which is declared as follows:
using TimePoint = std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<double>> TimePoint last_timestamp_
and I want to initialize it with zero, how do I do that? Thanks

using TimePoint = std::chrono::time_point<std::chrono::system_clock,
std::chrono::duration<double>>;
TimePoint last_timestamp_{};
It would actually work without the {} too, but imho it is better style to explicitly zero-initialize it.
You can read this two ways:
It internally sets the value of last_timestamp_ to 0.0s, or to its epoch.
It sets last_timestamp_ to 1970-01-01 00:00:00 UTC.
The reason you can say the second part is because it is a de-facto standard that all implementations track Unix Time with system_clock in C++11/14/17. For C++20 this industry practice has been officially specified.
Important note: This specification is strictly for time_points based on system_clock. One can not assume this epoch for all chrono time_points.
Presuming from the comments that your use looks like:
while (...)
{
if (std::chrono::system_clock::now() > last_timestamp_ + threshold)
{
// now() - last_timestamp_ > threshold
...
last_timestamp_ = std::chrono::system_clock::now();
}
};
Your first iteration will be true assuming threshold isn't larger than 51 years.
Just to future-proof your code, it's worth a comment:
TimePoint last_timestamp_{}; // 1970-01-01
Now if you change clocks for any reason, you know that you may have to revisit this initial value. For example on some platforms the epoch of file_clock will be far in the future, breaking this code if it switched to file_clock. C++20 offers syntax to make this initialization more explicit:
using namespace std::chrono_literals;
TimePoint last_timestamp_ = std::chrono::sys_days{1970y/1/1};
Now the comment is unnecessary.

Related

Converting from std::chrono:: to 32 bit seconds and nanoseconds?

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()?
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_cast to truncate the precision of tp to seconds precision. One important note is that time_point_cast truncates towards zero. So this code assumes that now() is after the clock's epoch and returns a non-negative time_point. If this is not the case, then you should use C++17's floor instead. floor always truncates towards negative infinity. I chose time_point_cast over floor only because of the [c++14] tag on the question.
The expression tp - tp_sec is a std::chrono::duration representing the time duration since the last integral second. This duration is implicitly converted to have units of nanoseconds. This implicit conversion is typically fine as all implementations of system_clock::duration have units that are either nanoseconds or coarser (and thus implicitly convertible to) nanoseconds. If your clock tracks units of picoseconds (for example), then you will need a duration_cast<nanoseconds>(tp - tp_sec) here to truncate picoseconds to nanoseconds precision.
Now you have the {seconds, nanoseconds} information in {tp_sec, ns}. It's just that they are still in std::chrono types and not uint32_t as desired. You can extract the internal integral values with the member functions .time_since_epoch() and .count(), and then static_cast those resultant integral types to uint32_t. The final static_cast are optional as integral conversions can be made implicitly. However their use is considered good style.

Time-stamping using std::chrono - How to 'filter' data based on relative time?

I want to time-tag a stream of data I produce, for which I want to use std::chrono::steady_clock.
These time-stamps are stored with the data ( as array of uint64 values?), and I will later need to process these time-stamps again.
Now, I haven't been using the std::chrono library at all so far, so I do need a bit of help on the syntax and best practices with this library.
I can get & store values using:
uint64_t timestamp = std::chrono::steady_clock::now().time_since_epoch().count();
but how do I best:
On reading the data create a timepoint from the uint64 ?
Get the ticks-per-second (uint64) value for the steady_clock?
Find a "cut-off" timepoint (as uint64) that lies a certain time (in seconds) prior a given timepoint?
Code snippets for the above would be appreciated.
I want to combine the three above essentially to do the following: Having an array of (increasing) time-stamp values (as uint64), I want to truncate it such that all data 'older' than last-time-stamp minus X seconds is thrown away.
Let's have a look at the features you might use in the cppreference documentation for chrono.
First off, you need to decide which clock you want to use. There is the steady_clock which you suggested, the high_resolution_clock and the system_clock.
high_resolution_clock is implementation dependent, so let's put this away unless we really need it. The steady_clock is guaranteed to be monotonic, but there is no guarantee of the meaning for the value you are getting. It's ideal for sorting events or measuring their intervals, but you can't get a timepoint out of it.
On the other hand, system_clock has a meaning, it's the UNIX epoch, so you can get a time value out of it, but is not guaranteed to be monotonic.
To get the period (duration of one tick) of a steady_clock, you have the period member:
auto period = std::chrono::steady_clock::period();
std::cout << "Clock period " << period.num << " / " << period.den << " seconds" << std::endl;
std::cout << "Clock period " << static_cast<double>(period.num) / period.den << " seconds" << std::endl;
Assuming you want to filter events that happened in the last few seconds using steady_clock values, you first need to compute the number of ticks in the time period you want and subtract it from now. Something along the lines of:
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
std::time_t t_c = std::chrono::system_clock::to_time_t(now - std::chrono::seconds(10));
And use t_c as cutoff point.
However, do not rely on std::chrono::steady_clock::now().time_since_epoch().count(); to get something meaningful - is just a number. The epoch for the steady_clock is usually the boot time. If you need a time, you should use system_clock (keeping in mind that is not monotonous).
C++20a introduces some more clocks, which are convertible to time.
As it took me far too long to figure it out from various sources today, I'm going to post my solution here as self-answer. ( I would appreciate comments on it, in case something is not correct or could be done better.)
Getting a clock's period in seconds and ticks-per-second value
using namespace std::chrono;
auto period = system_clock::period();
double period_s = (double) period.num / period.den;
uint64 tps = period.den / period.num;
Getting a clock's timepoint (now) as uint64 value for time-stamping a data stream
using namespace std::chrono;
system_clock::time_point tp_now = system_clock::now();
uint64 nowAsTicks = tp_now.time_since_epoch().count();
Getting a clock's timepoint given a stored uint64 value
using namespace std::chrono;
uint64 givenTicks = 12345; // Whatever the value was
system_clock::time_point tp_recreated = system_clock::time_point{} + system_clock::duration(givenTicks);
uint64 recreatedTicks = tp_now.time_since_epoch().count();
Assert( givenTicks == recreatedTicks ); // has to be true now
The last ( uint64 to timepoint ) was troubling me the most. The key-insights needed were:
(On Win10) The system_clock uses a time-resolution of 100 nanoseconds. Therefore one can not directly add std::chrono::nanoseconds to its native time points. (std::chrono:system_clock_time_point)
However, because the ticks are 100's of nanoseconds, one can also not use the next higher duration unit (microseconds) as it cannot be represent as an integer value.
One could use use an explicit cast to microseconds, but that would loose the 0.1us resolution of the the tick.
The proper way is to use the system_clock's own duration and directly initialize it with the stored tick value.
In my search I found the following resources most helpful:
Lecture of Howard Hinnant on YouTube - extremely helpful. I wish I would have started here.
cppreference.com on time_point and duration and time_since_epoch
cplusplus.com on steady clock and time_point
A nice place to look as usual is the reference manual :
https://en.cppreference.com/w/cpp/chrono
In this case you are looking for :
https://en.cppreference.com/w/cpp/chrono/clock_time_conversion
Since really you are using a clock with "epoch" 1/1/70 as origin and ms as unit.
Then just use arithmetic on durations to do the cutoff things you want :
https://en.cppreference.com/w/cpp/chrono/duration
There are code examples at bottom of each linked page.

What is the std::chrono::time_point equivalent of std::numeric_limits::infinity()?

Suppose I want to call my_func() periodically at CALL_PERIOD intervals
auto last_call_time = CHRONO_NEGATIVE_INFINITY;
while (true)
{
if (std::chrono::system_clock::now() - last_call_time > CALL_PERIOD)
{
last_call_time = std::chrono::system_clock::now();
my_func();
}
}
What would be an appropriate CHRONO_NEGATIVE_INFINITY such that the line
std::chrono::system_clock::now() - last_call_time > CALL_PERIOD
will always evaluate true on the first run?
I've tried time_point::min() but that doesn't seem to work
One of the main reasons to have a type like std::optional is so that we don't have to have hacks like picking a specific value to mean "not a value":
std::optional<std::chrono::system_clock::time_point> last_call_time;
while (true)
{
auto curr = std::chrono::system_clock::now()
if (!last_call_time || (curr - *last_call_time) > CALL_PERIOD)
{
last_call_time = std::chrono::system_clock::now();
my_func();
}
}
If C++17 is not available to you, and/or you're just dead-set on using the old hack of picking a special value, you can get the clock's rep type and compute the minimum possible integer of it:
using sys_clock = std::chrono::system_clock;
constexpr auto min_int = std::numeric_limits<sys_clock::rep>::min();
constexpr sys_clock::duration min_duration(min_int);
sys_clock::time_point min_time(min_duration);
Of course, min_time is still a valid time, so it's unlike any "infinity" representation for floats.
The rationale that there is no time_point::infinity equivalent is that time_points are simple wrappers around arithmetic types. Simplistic wrappers lead to the highest performing code. And this same rationale is also a clue that for special cases, time_point::infinity actually does exist!
Let me elaborate further on that entirely confusing first paragraph...
system_clock::time_point is a simple wrapper around a duration. Exactly which duration is unspecified, but let's just say it is nanoseconds. And nanoseconds is a simple wrapper around a 64 bit signed integer (say long long).
long long has no representation of +/- INFINITY. But it does have a minimum value: -9223372036854775808.
A shortcut for putting this value into a duration (say nanoseconds) is nanoseconds::min(), and a shortcut to putting this value into system_clock::time_point is system_clock::time_point::min().
However when you do so, it is an invitation for plain old signed integral overflow. After all:
cout << (10 - numeric_limits<long long>::min() > 1) << '\n';
overflows and prints out 0 (false). And that's precisely why:
auto CHRONO_NEGATIVE_INFINITY = system_clock::time_point::min();
didn't work.
There are several ways to get your code to work. Which is best for your application is up to you. But now that <chrono> is just a little less mysterious, you can better make that decision.
Perhaps the easiest way is to set CHRONO_NEGATIVE_INFINITY to something that isn't quite so negative so that you don't risk overflow:
auto CHRONO_NEGATIVE_INFINITY = std::chrono::system_clock::now() - CALL_PERIOD;
C++20 standardizes the existing practice that system_clock's epoch is 1970-01-01, so here's another possibility (that works back to C++11):
// Set CHRONO_NEGATIVE_INFINITY to 1970-01-01 00:00:00 UTC
auto CHRONO_NEGATIVE_INFINITY = std::chrono::system_clock::time_point{};
But let's say that for some reason you really, really need a time_point that is infinitely in the past. You can do that too, it just takes a little more work. float and double are arithmetic types too, and they do have a representation of INFINITY! So you can just build a time_point out of one of those types.
using dsec = std::chrono::duration<double>;
using tp_dsec = std::chrono::time_point<std::chrono::system_clock, dsec>;
auto CHRONO_NEGATIVE_INFINITY = tp_dsec{dsec{-INFINITY}};
The first line makes dsec a name for double-based-seconds. The second line makes tp_dsec a name for a system_clock-based time_point using dsec as its representation. And then the third line just stuffs negative infinity into a tp_dsec. The rest of your code will implicitly convert to double-based time_points and durations when doing the test.
If you rewrite your test like this:
auto last_call_time = std::chrono::system_clock::min();
...
if (std::chrono::system_clock::now() - CALL_PERIOD > last_call_time)
you shouldn't overflow.
Use 0:
std::chrono::duration CALL_PERIOD(std::chrono::seconds(2));
std::chrono::steady_clock::time_point last_call_time; //auto init to 0,
// or can use explicit initialization to 0:
// std::chrono::steady_clock::time_point last_call_time(std::chrono::seconds(0));
while (true)
{
auto now = std::chrono::steady_clock::now();
if (now - last_call_time > CALL_PERIOD)
{
last_call_time = now;
my_func();
}
}

Difference between two nanosecond chrono::time_points, but in seconds?

I have a timestamp (nanoseconds since epoch):
uint64_t ts = .....;
and I'd like to check whether it is more than 5 seconds older than the current system time.
So I need to convert the timestamp to, a time_point? and then subtract this from the current time (in nanoseconds), checking whether its value is greater than chrono::duration::seconds(5)?
Got this so far:
const std::chrono::time_point tstp(std::chrono::duration_cast<std::chrono::nanoseconds>(rawNanos));
const std::chrono::time_point now = std::chrono::high_resolution_clock::now();
const bool old = now - tstp > std::chrono::seconds(5);
but struggling because of the constructor type for time_point.
You should not use high_resolution_clock for this. On some platforms high_resolution_clock counts time since the computer was booted up, not time since the Unix epoch.
Although not specified by the standard, the de facto standard is that on all platforms, system_clock counts time since the Unix epoch.
I find it handy to first declare a templated type alias that is a time_point based on system_clock, templated on duration. This makes it easy to create a time_point of any precision that counts time since the Unix epoch:
template <class D>
using sys_time = std::chrono::time_point<std::chrono::system_clock, D>;
Given that:
uint64_t ts = 1235;
using namespace std::chrono;
const bool old = system_clock::now() >
sys_time<nanoseconds>{nanoseconds{ts}} + seconds{5};
In C++14 you'll be able to write:
const bool old = system_clock::now() >
sys_time<nanoseconds>{nanoseconds{ts}} + 5s;

Get seconds since epoch in Linux

Is there cross-platform solution to get seconds since epoch, for windows i use
long long NativesGetTimeInSeconds()
{
return time (NULL);
}
But how to get on Linux?
You're already using it: std::time(0) (don't forget to #include <ctime>). However, whether std::time actually returns the time since epoch isn't specified in the standard (C11, referenced by the C++ standard):
7.27.2.4 The time function
Synopsis
#include <time.h>
time_t time(time_t *timer);
Description
The time function determines the current calendar time. The encoding of the value is unspecified. [emphasis mine]
For C++, C++11 and later provide time_since_epoch. However, before C++20 the epoch of std::chrono::system_clock was unspecified and therefore possibly non-portable in previous standards.
Still, on Linux the std::chrono::system_clock will usually use Unix Time even in C++11, C++14 and C++17, so you can use the following code:
#include <chrono>
// make the decltype slightly easier to the eye
using seconds_t = std::chrono::seconds;
// return the same type as seconds.count() below does.
// note: C++14 makes this a lot easier.
decltype(seconds_t().count()) get_seconds_since_epoch()
{
// get the current time
const auto now = std::chrono::system_clock::now();
// transform the time into a duration since the epoch
const auto epoch = now.time_since_epoch();
// cast the duration into seconds
const auto seconds = std::chrono::duration_cast<std::chrono::seconds>(epoch);
// return the number of seconds
return seconds.count();
}
In C.
time(NULL);
In C++.
std::time(0);
And the return value of time is : time_t not long long
The native Linux function for getting time is gettimeofday() [there are some other flavours too], but that gets you the time in seconds and nanoseconds, which is more than you need, so I would suggest that you continue to use time(). [Of course, time() is implemented by calling gettimeofday() somewhere down the line - but I don't see the benefit of having two different pieces of code that does exactly the same thing - and if you wanted that, you'd be using GetSystemTime() or some such on Windows [not sure that's the right name, it's been a while since I programmed on Windows]
The Simple, Portable, and Proper Approach
#include <ctime>
long CurrentTimeInSeconds()
{
return (long)std::time(0); //Returns UTC in Seconds
}