How to convert std::chrono::monotonic_clock::now() to milliseconds and cast it to long?
using steady_clock or high_resolution_clock from chrono is also same. I have seen into std::chrono::duration_cast<std::chrono::milliseconds> but I only want the current timestamp and not any duration gaps.
The current timestamp is defined with respect to some point in time (hence it is a duration). For instance, it is "typical" to get a timestamp with respect to the beginning of the Epoch (January 1st 1970, in Unix). You can do that by using time_since_epoch():
namespace chr = std::chrono;
chr::time_point<chr::steady_clock> tp = chr::steady_clock::now();
std::cout << "hours since epoch: "
<< chr::duration_cast<chr::hours>(tp.time_since_epoch()).count()
<< '\n';
To get the value in milliseconds you would need to cast it to std::chrono::milliseconds, instead.
All the built-in clocks have an associated "epoch" which is their base time. The actual date/time of the epoch is not specified, and may vary from clock to clock.
If you just want a number for comparisons then some-clock::now().time_since_epoch() will give you a duration for the time since the epoch for that clock, which you can convert to an integer with the count() member of the duration type. The units of this will depend on the period of the clock. If you want specific units then use duration_cast first:
typedef std::chrono::steady_clock clk;
unsigned long long milliseconds_since_epoch=
std::chrono::duration_cast<std::chrono::milliseconds>(
clk::now().time_since_epoch()).count();
As I said, this is only good for comparisons, not as an absolute time stamp, since the epoch is unspecified.
If you need a UNIX timestamp then you need to use std::chrono::system_clock, which has a to_time_t() function for converting a time_point to a time_t.
Alternatively, you can take a baseline count at a particular point in your program, along with the corresponding time from gettimeofday or something, and then use that to convert relative counts to absolute times.
Related
I am trying to write a function, which will return the current time in microseconds since 1970. While a debugging I noticed, that the returned numbers are too small. For example: 269104616249. I also added static_assert to check the returned value type is int64_t, which i big enough to hold 292471 years in microseconds. So integer overflow should not be a case here.
What am I doing wrong?
Here is my code:
int64_t NowInMicroseconds() {
static_assert(std::is_same<decltype(duration_cast<microseconds>(high_resolution_clock::now().time_since_epoch()).count()), int64_t>::value);
return duration_cast<microseconds>(high_resolution_clock::now().time_since_epoch()).count();
}
int64_t result = NowInMicroseconds();
There are three chrono-supplied clocks in C++11/14/17 (more in C++20):
system_clock: This measures Unix Time (time since 1970 excluding leap seconds).1
steady_clock: Like a stop-watch. Great for timing, but it can not tell you the time of day.
high_resolution_clock: This has the disadvantages of system_clock and steady_clock, and the advantages of neither. Typically it is a type alias to either system_clock or steady_clock, and which one differs with platform.
You have to use system_clock for measuring time since 1970. Note that this is measured in UTC, not your local time zone. In C++11/14/17 to get the local time since 1970, you will have to either manually take your time zone into account, or use this C++20 chrono preview library.
std::int64_t
NowInMicroseconds()
{
using namespace std::chrono;
return duration_cast<microseconds>(system_clock_clock::now().time_since_epoch()).count();
}
Consider returning a strong type which means "microseconds since 1970" instead of an integral type. Strong type safety helps you find your logic errors at compile time:
std::chrono::time_point<std::chrono::system_clock, std::chrono::microseconds>
NowInMicroseconds()
{
using namespace std::chrono;
return time_point_cast<microseconds>(system_clock.now());
}
1 This is unspecified in C++11/14/17, but is true on all implementations. C++20 finally nails this epoch down in the spec.
I have a double representing the time in days since midnight (local time zone) 1 Jan 1970 and a string representing the time zone. I would like to convert these to a
date::zoned_time
using Howard Hinnant's date and time zone library.
The background is I need to convert date-times to and from doubles to use in an analytics library. I will also receive date-times as doubles from excel in a local or user-specified time zone.
Here is one attempt I made
using namespace date;
using namespace std::chrono;
typedef date::zoned_time<std::chrono::seconds> datetime;
const double UNIX_MINUS_EXCEL_EPOCH = 25569.0;
const double SECONDS_PER_DAY = 24.0 * 60.0 * 60.0;
datetime timePointFromDouble(double x)
{
double seconds = (x - UNIX_MINUS_EXCEL_EPOCH) * SECONDS_PER_DAY;
system_clock::duration d = duration_cast<system_clock::duration>(duration<double>(seconds));
system_clock::time_point t = system_clock::time_point(d);
auto xx = make_zoned("America/Chicago", t);
return xx;
}
It doesn't compile because the result of make_zoned has the wrong type. Also, I am not convinced it correctly maps the input time in days to the output date-time because of leap seconds and days where daylight saving changes.
Specification:
x is a measure of days since 1899-12-30 00:00:00 in America/Chicago.
Solution:
using datetime = date::zoned_seconds;
datetime
timePointFromDouble(double x)
{
using namespace date;
using namespace std::chrono;
using ddays = duration<double, days::period>;
constexpr auto excel_epoch = local_days{1_d/January/1970} -
local_days{30_d/December/1899};
return datetime{"America/Chicago",
local_seconds{round<seconds>(ddays{x} - excel_epoch)}};
}
Explanation:
The reason your version doesn't compile is because of the conversion to system_clock::time_point, which in practice has a precision of microseconds or finer. But your result type has a precision of seconds, so the library is refusing to implicitly truncate your high-precision t to your lower-precision xx.
The easiest way to fix this is to time_point_cast<seconds>(t). But there's more fun to be had...
<chrono> lives and dies by handling the conversions for you. Any time you're doing the conversions yourself, you should opt for removing those conversions in favor of letting <chrono> do them. This will usually simplify your code, and it may just catch a conversion error.
<chrono> knows about how to convert among various durations, but not about the Excel epoch, so that's one conversion we can't avoid. But we can express that epoch in a higher level language than the mysterious constant 25569.0.
So, from the top:
date::zoned_seconds is a simpler way to write date::zoned_time<std::chrono::seconds>. It is just a convenience typedef.
ddays is a custom duration unit which represents 1 day with a double. This is convenient for converting the scalar input x directly into a <chrono> duration. It is best to get into the <chrono> type system as soon as possible.
The epoch difference is the amount of time between 1970-01-01 and 1899-12-30. The units will be days as I've coded it, but that is an unimportant detail. <chrono> takes care of the units for you.
I'm using local_days as opposed to sys_days to compute the epoch difference. This is a largely symbolic gesture to communicate that the epoch is in a local time, not UTC. It doesn't make a difference in the actual value of the constant that is computed.
Because of the way you worded the question, I assumed you would prefer day-month-year ordering in the code. This is a purely stylistic choice.
If you are writing this in C++11, excel_epoch will have to be made const instead of constexpr. The difference is that C++11 has to compute this constant at run-time and C++14 and later can compute it at compile-time.
When converting from double-based units to integral-based units, I like to use round instead of duration_cast. The difference is that round chooses the nearest representable value, and duration_cast truncates towards zero to the nearest representable value. The round strategy is more likely to result in stable round-trip conversions between the double and integral representations, whereas truncation is more likely to expose one-off differences due to round-off error in the double representation.
The last line has to explicitly get us from double-based to integral-based units, and has to specify seconds to match with the return type, but does not have to worry about converting days into seconds.
The last line uses local_seconds to convert the duration into a time_point because this duration represents a measure in the local time of America/Chicago, as opposed to a measure in UTC. This fixes the epoch to 1899-12-30 00:00:00 in America/Chicago as opposed to 1899-12-30 00:00:00 UTC.
The result does not take leap seconds into account. This is the correct thing to do, because neither does Excel nor system_clock. Just about every computer-based time-keeping protocol out there doesn't count leap seconds. Here is a good description of Unix Time. If you want to convert to a system that counts leap seconds, this library can do that too. It is called utc_clock/utc_time.
The result does take daylight savings time into account for Chicago, including the changes to the daylight savings rules over the years, as best as the IANA database can do (which is exact as far as I know).
I have the following string
2013-04-12 16:00:15.041
What is the C++ way to convert this string into a 64bit UNIX timestamp? Most question on here deal with only having the timestamp until seconds but in my case I also need to include the milliseconds.
Parse the string into its components and construct a std::chrono::time_point. In C++20, you will have the utc_clock in <chrono>, that is, a utc_time, or else std::chrono::local_t. In C++11 and up, you have std::chrono::system_clock.
There’s sort of a chicken-and-egg problem in converting the broken-down-time into STL time objects, though: usually, doing that gives you your answer with just the C library. You can use std::get_time(), on an istringstream if necessary, to convert your string to a tm and the C standard library function mktime() to convert the tm to a time_t, which you can then pass to std::chrono::system_clock::from_time_t()to convert to a std::chrono::time_point—except that, on UNIX/Linux, time_t is already a UNIX timestamp!
Your example has no time zone specified, so you might or might not need to do time-zone conversion.
The utc_clock uses the same Epoch as POSIX, January 1, 1970, so the time_since_epoch() member function of utc_time/time_point gives you the answer as a std::chrono::duration. If you are using system_clock instead, the Epoch is implementation-defined (but almost always the same Epoch, too), so you will want to find a time_point for 12:00 AM January 1, 1970, and subtract it from the time_point you calculate to get a duration. You can convert this duration, call it moment, into seconds with std::chrono::seconds(moment).count(). You can then convert to int64_t or uint64_t (from <cstdint>) if you want to be sure to have an exactly 64-bit value.
There are a few different UNIX time formats, but if you want to convert your time in milliseconds into a C/POSIX timespec with nanoseconds, rather than the obsolete formats in <sys/time.h>, set .tv_nsec to the number of milliseconds times one million, or convert from std::chrono::milliseconds to std::chrono::nanoseconds.
If the purpose of this is to work with filesystem timestamps, you might want std::filesystem::file_time_type.
I have a below code from which we are trying to get current timestamp in microseconds since epoch time but we are using steady_clock.
inline uint64_t get_timestamp()
{
std::chrono::time_point<std::chrono::steady_clock> ts = std::chrono::steady_clock::now();
return std::chrono::duration_cast<std::chrono::microseconds>(ts.time_since_epoch()).count();
}
Is this the right way to do that since as per my understanding steady_clock is used to measure the passage of time not to get the current time of day? Or should I use system_clock for this like as shown below:
inline uint64_t get_timestamp()
{
std::chrono::time_point<std::chrono::system_clock> ts = std::chrono::system_clock::now();
return std::chrono::duration_cast<std::chrono::microseconds>(ts.time_since_epoch()).count();
}
I need to use std::chrono package only since that's what all our code is using.
The epochs of the chrono clocks are unspecified. But practically you can think of the chrono clocks this way:
The epoch of steady_clock is the time your application launched plus a signed random offset. I.e. you can't depend upon the epoch being the same across application launches. But the epoch will remain stable while an application is running.
The epoch of system_clock is time since New Years 1970, not counting leap seconds, in the UTC timezone. Different implementations implement this with varying precision: libc++ counts microseconds, VS counts 1/10 of microseconds, and gcc counts nanoseconds.
high_resolution_clock is sometimes a type alias for steady_clock and sometimes a type alias for system_clock.
For a time stamp in microseconds I recommend first defining this type alias:
using time_stamp = std::chrono::time_point<std::chrono::system_clock,
std::chrono::microseconds>;
Store that, instead of uint64_t. The type safety of this type will save you countless run time errors. You'll discover your errors at compile time instead.
You can get the current time_stamp with:
using namespace std::chrono;
time_stamp ts = time_point_cast<microseconds>(system_clock::now());
Another possibility for people who couldn't get other solutions to work:
uint64_t microseconds_since_epoch = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
Is there any class in c++ for representing time in milliseconds ?
I need to hold time and compare values, set time from device. Do I need to write my own or there is already ? I looked at <ctime> and time_t but it can holds only seconds.
Well, C++11's std::chrono has a concept of time duration, one of which is milliseconds.
If you're simply dealing with millisecond time durations, then an integer type will be fine; perhaps using typedef to give it a friendly name.
POSIX does this with time_t (representing seconds) and clock_t (representing microseconds); standard C also specifies these types, but doesn't specify which units they use.
If you want to mix units, then std::chrono, or boost::chrono if you can't use C++11, have some nice types such as duration that wrap up integer values and automatically change scale as appropriate; so you can write things like duration d = seconds(4) + milliseconds(123).