Getting current time with millisecond precision using put_time in C++ - c++

I am using the following code to get the current time in C++.
std::time_t t = std::time(nullptr);
std::time(&t);
std::cout << std::put_time(std::localtime(&t), "%X,");
However, this gives me time in HH::MM::SS. But for my application I also want to include time in milliseconds. Is there anyway to get something like HH::MM::SS::msecs using std::put_time?
Or what are the alternatives to get the system time with milliseconds precision inside a C++ program?

Here's one example using some C++11 <chrono> features. If you can use C++20, check out the new <chrono> features for more goodies or take a look at Howard Hinnants Date library.
#include <chrono>
#include <cstdint>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <string>
#include <type_traits>
// A C++11 constexpr function template for counting decimals needed for
// selected precision.
template<std::size_t V, std::size_t C = 0,
typename std::enable_if<(V < 10), int>::type = 0>
constexpr std::size_t log10ish() {
return C;
}
template<std::size_t V, std::size_t C = 0,
typename std::enable_if<(V >= 10), int>::type = 0>
constexpr std::size_t log10ish() {
return log10ish<V / 10, C + 1>();
}
// A class to support using different precisions, chrono clocks and formats
template<class Precision = std::chrono::seconds,
class Clock = std::chrono::system_clock>
class log_watch {
public:
// some convenience typedefs and "decimal_width" for sub second precisions
using precision_type = Precision;
using ratio_type = typename precision_type::period;
using clock_type = Clock;
static constexpr auto decimal_width = log10ish<ratio_type{}.den>();
static_assert(ratio_type{}.num <= ratio_type{}.den,
"Only second or sub second precision supported");
static_assert(ratio_type{}.num == 1, "Unsupported precision parameter");
// default format: "%Y-%m-%dT%H:%M:%S"
log_watch(const std::string& format = "%FT%T") : m_format(format) {}
template<class P, class C>
friend std::ostream& operator<<(std::ostream&, const log_watch<P, C>&);
private:
std::string m_format;
};
template<class Precision, class Clock>
std::ostream& operator<<(std::ostream& os, const log_watch<Precision, Clock>& lw) {
// get current system clock
auto time_point = Clock::now();
// extract std::time_t from time_point
std::time_t t = Clock::to_time_t(time_point);
// output the part supported by std::tm
os << std::put_time(std::localtime(&t), lw.m_format.c_str());
// only involve chrono duration calc for displaying sub second precisions
if(lw.decimal_width) { // if constexpr( ... in C++17
// get duration since epoch
auto dur = time_point.time_since_epoch();
// extract the sub second part from the duration since epoch
auto ss =
std::chrono::duration_cast<Precision>(dur) % std::chrono::seconds{1};
// output the sub second part
os << std::setfill('0') << std::setw(lw.decimal_width) << ss.count();
}
return os;
}
int main() {
// default precision, clock and format
log_watch<> def_cp; // <= C++14
// log_watch def; // >= C++17
// alt. precision using alternative formats
log_watch<std::chrono::milliseconds> milli("%X,");
log_watch<std::chrono::microseconds> micro("%FT%T.");
// alt. precision and clock - only supported if the clock is an alias for
// system_clock
log_watch<std::chrono::nanoseconds,
std::chrono::high_resolution_clock> nano("%FT%T.");
std::cout << "def_cp: " << def_cp << "\n";
std::cout << "milli : " << milli << "\n";
std::cout << "micro : " << micro << "\n";
std::cout << "nano : " << nano << "\n";
}
Example output:
def_cp: 2019-11-21T13:44:07
milli : 13:44:07,871
micro : 2019-11-21T13:44:07.871939
nano : 2019-11-21T13:44:07.871986585

The accepted answer is a good one, but I would like to demonstrate doing this with an open-source, third-party, date handling library:
auto now = std::chrono::system_clock::now();
std::cout << date::format("%T", std::chrono::floor<std::chrono::milliseconds>(now));
This just output, for me: 10:01:46.654.
The fractional seconds separator is locale specific. In Sweden, where I reside, they use the comma as a separator. date::format allows supplying a std::locale, so we can force the use of the Swedish locale, for example, on my machine:
auto now = std::chrono::system_clock::now();
std::cout << date::format(std::locale("sv-SE"), "%T", std::chrono::floor<std::chrono::milliseconds>(now));
Now the ouput is: 10:02:32,169.
This formatting has been accepted in C++20, so you will get this when the vendors have implemented it :)
Of course, if the "%X" formatting is really want you want, then you cannot have decimal seconds and need to append them yourself:
auto now = std::chrono::system_clock::now();
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch() % std::chrono::seconds{1});
std::cout << date::format("%X", std::chrono::floor<std::chrono::milliseconds>(now)) << "," << ms.count();
Note that I am using ms.count() because in C++20 streaming a duration will append the units as well, meaning that << ms would output something like 123ms.

Related

Converting time in milliseconds since epoch to time in yy-dd-hh-ss format

I have a bunch of tasks which are in the order of microseconds, the below code prints only until seconds (Thu Oct 21 12:48:20 2021) so comparing the values of start and finish always ends up giving 0. I want to be able to compare in the order of milliseconds and microseconds. Is there a function to help with this?
Also, is there a way to convert uint64_t current1 = std::chrono::system_clock::now().time_since_epoch().count(); to time_t to print out the current time based on the count()?
const auto p1 = std::chrono::system_clock::now();
std::time_t now = std::chrono::system_clock::to_time_t(p1);
std::cout << "now: " << std::ctime(&now);
I recommend skipping the C timing API entirely. It is error-prone and doesn't handle sub-second precision.
If UTC (as opposed to local time) is ok, then there is a header-only, open-source preview of C++20 that works with C++11/14/17:
#include "date/date.h"
#include <chrono>
#include <iostream>
int
main()
{
using date::operator<<;
const auto p1 = std::chrono::system_clock::now();
std::cout << "now: " << p1 << '\n';
}
Output:
now: 2021-10-21 20:28:15.754423
To port the above program to C++20 (which is already shipping in the latest Visual Studio), just drop the #include "date/date.h" and using date::operator<<;.
If you need local time, that can be also be had in C++20 (shipping in VS), but the open-source preview of C++20 is no longer header only. There exists one source file that needs to be compiled, and depending on your needs, might require a download of the IANA tz database.
#include "date/tz.h"
#include <chrono>
#include <iostream>
int
main()
{
using namespace date;
using namespace std::chrono;
const auto p1 = system_clock::now();
std::cout << "now: " << zoned_time{current_zone(), p1} << '\n';
}
Output:
now: 2021-10-21 16:28:15.754423 EDT
The above syntax assumes C++17. For C++11/14 the template parameter for zoned_time needs to be specified: zoned_time<system_clock::duration>.
The above program ports to C++20 by dropping #include "date/tz.h" and using namespace date;.
In either program you can truncate to millisecond precision with:
const auto p1 = floor<milliseconds>(system_clock::now());
time_t is usually an integer specifying (whole) seconds.
You could get the millseconds by subtracting the whole-second time_t from now:
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
p1 - std::chrono::system_clock::from_time_t(now)).count();
or using operator%:
auto ms = std::chrono::time_point_cast<std::chrono::milliseconds>p1)
.time_since_epoch() % std::chrono::seconds(1);
std::cout << ms.count();
Example how you could do the formatting:
#include <chrono>
#include <iostream>
#include <iomanip>
int main() {
using Clock = std::chrono::system_clock;
using Precision = std::chrono::milliseconds;
auto time_point = Clock::now();
// extract std::time_t from time_point
std::time_t t = Clock::to_time_t(time_point);
// output the part supported by std::tm
std::cout << std::put_time(std::localtime(&t), "%FT%T."); // select format here
// get duration since epoch
auto dur = time_point.time_since_epoch();
// extract the sub second part from the duration since epoch
auto ss =
std::chrono::duration_cast<Precision>(dur) % std::chrono::seconds{1};
// output the millisecond part
std::cout << std::setfill('0') << std::setw(3) << ss.count();
}

ways to record time in C++

What is the most adequate way to record time in C++ (not time elapsed but time)
I am now trying something like
#include <iostream>
#include <ctime>
#include <ratio>
#include <chrono>
int main ()
{
using namespace std::chrono;
high_resolution_clock::time_point t1= high_resolution_clock::now();
time_t tt=system_clock::to_time_t(t1);
std::cout<<"Right now it is: " << ctime(&tt)<<std::endl;
}
but I see that this requires (or I am understanding it wrong??) that we convert from chrono to the the C way of timing with to_time so doesn't defeat the point of using chrono?
The usual examples I found while searching are about elapsed time, but I am wondering about just recording time since I am not that familiar with C++11
As of C++17 std::chrono has no facilities to easily decompose a std::chrono::system_clock::time_point into its calandar date and wall clock time other than to convert the time_point to a time_t and use the date/time formatting functionality inherited from C.
It's posible to do it using only std::chrono, but not simple. For instance something like this can get the wall clock time from a std::chrono::system_clock::time_point:
std::string time_of_day(const std::chrono::system_clock::time_point& time_point)
{
using days = std::chrono::duration<int, std::ratio<86400>>;
auto midnight = std::chrono::floor<days>(time_point);
auto time_since_midnight = time_point - midnight;
auto hours = std::chrono::floor<std::chrono::hours>(time_since_midnight);
auto minutes = std::chrono::floor<std::chrono::minutes>(time_since_midnight - hours);
auto seconds = std::chrono::floor<std::chrono::seconds>(time_since_midnight - minutes - hours);
std::ostringstream oss;
oss << hours.count() << ":" << std::setw(2) << std::setfill('0') << minutes.count() << ":" << seconds.count();
return oss.str();
}
int main() {
std::cout << time_of_day(std::chrono::system_clock::now());
}
Live Demo
It's not simple at all, and I'm sure there are corner cases I've neglected, but it works using only std::chrono facilities.
C++20 will introduce a couple of ways to do this more easily. At time of writing no standard library implementation has implemented either of them though.
First of all, if you want the full date/time, there will be an overloaded operator<<(std::ostream&, const std::chrono::system_clock::time_point&) that will format and print that for you:
int main() {
std::cout << std::chrono::system_clock::now();
}
If you want just the date or time part of the time_point, std::chrono::day_month_year, std::chrono::time_of_day, and friends can be used to decompose the time_point.
For instance, the above time_of_day function could be done much more simply like this:
std::chrono::time_of_day time_of_day(const std::chrono::sytem_clock::time_point& time_point)
{
auto midnight = std::chrono::floor<std::chrono::days>(time_point);
return std::chrono::time_of_day{time_point - midnight};
}
int main() {
std::cout << time_of_day(std::chrono::system_clock::now());
}
See P3055 for more info.
The other method is the new std::format family of functions. There will be a std::formatter specialization for std::chrono::system_clock::time_point that will let you format a time_point to a string using a strftime-like format string. For instance, the output of the following will be very similar (if not the same) as the previous two time_of_day functions:
int main() {
std::cout << std::format("{%T}", std::chrono::system_clock::now());
}
See P0645 and P1361 for more info.
auto t1 = system_clock::now(); is the fix
time_point is
template<
class Clock,
class Duration = typename Clock::duration
> class time_point;
and system_clock::to_time_t wants time_point<system_clock> type, but you provide completly different type time_point<high_resolution_clock>
read the Note under this link
Notes
The high_resolution_clock is not implemented consistently across different standard library implementations, and its use should be avoided. It is often just an alias for std::chrono::steady_clock or std::chrono::system_clock, but which one it is depends on the library or configuration. When it is a system_clock, it is not monotonic (e.g., the time can go backwards). For example, for gcc's libstdc++ it is system_clock, for MSVC it is steady_clock, and for clang's libc++ it depends on configuration.
Generally one should just use std::chrono::steady_clock or std::chrono::system_clock directly instead of std::chrono::high_resolution_clock: use steady_clock for duration measurements, and system_clock for wall-clock time.
int main()
{
using namespace std::chrono;
auto nowTime = std::chrono::system_clock::now();
auto tt = system_clock::to_time_t(nowTime);
std::cout << "Right now it is: " << ctime(&tt) << std::endl;
}
the best performance way is :
#include <stdint.h>
uint64_t get_time_us() {
struct timeval tv {0, 0};
gettimeofday(&tv, NULL);
return tv.tv_sec * 1000000 + tv.tv_usec; // microsecond
}
uint64_t t0 = get_time_us();
// do_something
uint64_t t1 = get_time_us();
int time_cost = t1 - t0;
and for C++11:
std::chrono::high_resolution_clock::time_point t1, t2
t1 = std::chrono::high_resolution_clock::now();
// do_something
t2 = std::chrono::high_resolution_clock::now();
int time_ms = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count(); // ms
// int time_us = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count(); // us
for boost:
#include <date_time/posix_time/posix_time.hpp>
boost::posix_time::ptime t1(boost::posix_time::microsec_clock::universal_time());
// do_something
boost::posix_time::ptime t2(boost::posix_time::microsec_clock::universal_time());
boost::posix_time::time_duration diff(t2 - t1);
int micro_sec = diff.total_microseconds();

Return a tuple corresponding to variadic template in C++17

How to return a tuple from a function that takes a list of variadic template? The tuple types should be the same to the argument types.
template <typename ... T, typename D>
std::tuple<T...> foo(D&& Duration) {
// How to do this?
if constexpr(sizeof... (args) > 0) {
...
}
// What to return?
}
The idea is to use C++17 structure binding so I can do something like this:
auto var = std::chrono::seconds(19874);
auto [h, m] = foo<std::chrono::hours, std::chrono::minutes> (var);
auto [m, s, ms] = foo<std::chrono::minutes, std::chrono::seconds, std::chrono::milliseconds>(var);
For both cases, the sum (h:m or m:s:ms) should be 19874 seconds.
This code should do what you ask. It constructs the tuple using an initializer list of calls to chrono_extract for each of the ouptut types. The initializer list parameters are processed in order according to the standard, so this shouldn't be sensitive to any reordering even though it might look like it from the use of the commas. The chrono_extract function casts the input duration to the type of the output duration, then subtracts the output from the input (which is passed by reference, so its value will be reflected in chrono_components). In order to correctly run the algorithm, we need to find the smallest time component in the list, and run all calculations at the smallest resolution (otherwise there will be duration casting errors). Also provided is an assertion to make sure that the return duration types are in decreasing order because the function will not operate correctly if they are in a different order. One possible enhancement that could be added is to also return a "remainder" in the tuple (that is the same as the input type) if there is anything left over from the decomposition (as in the first test case in the code below).
#include <chrono>
#include <iostream>
#include <tuple>
#include <type_traits>
template <typename lhs_t, typename rhs_t, typename... other_ts>
constexpr void assert_decreasing_ratios() {
static_assert(std::ratio_greater_v<typename lhs_t::period,
typename rhs_t::period>,
"Periods are non-decreasing.");
if constexpr (sizeof...(other_ts)) {
assert_decreasing_ratios<rhs_t, other_ts...>();
}
}
template <typename return_duration_t, typename input_duration_t>
return_duration_t chrono_extract(input_duration_t& value) {
auto extracted = std::chrono::duration_cast<return_duration_t>(value);
value -= extracted;
return extracted;
}
template <typename... return_ts, typename duration_t>
std::tuple<return_ts...> chrono_components(duration_t value) {
assert_decreasing_ratios<return_ts...>();
using smallest_t = std::tuple_element_t<sizeof...(return_ts) - 1,
std::tuple<return_ts...>>;
auto small_value = std::chrono::duration_cast<smallest_t>(value);
return {chrono_extract<return_ts>(small_value)...};
}
int main()
{
std::chrono::seconds before(19874);
{
auto [h, m] = chrono_components<std::chrono::hours,
std::chrono::minutes>(before);
std::chrono::seconds after(h + m);
std::cout << h.count() << " hours "
<< m.count() << " minutes = "
<< after.count() << " seconds\n";
}
{
auto [m, s, ms] = chrono_components<std::chrono::minutes,
std::chrono::seconds,
std::chrono::milliseconds>(before);
auto after =
std::chrono::duration_cast<std::chrono::seconds>(m + s + ms);
std::cout << m.count() << " minutes "
<< s.count() << " seconds "
<< ms.count() << " milliseconds = "
<< after.count() << " seconds\n";
}
}
Output
5 hours 31 minutes = 19860 seconds
331 minutes 14 seconds 0 milliseconds = 19874 seconds
The first line shows that the seconds value has been truncated because it's not an exact number of minutes.

getting chrono time in specific way

I have following C code:
uint64_t combine(uint32_t const sec, uint32_t const usec){
return (uint64_t) sec << 32 | usec;
};
uint64_t now3(){
struct timeval tv;
gettimeofday(&tv, NULL);
return combine((uint32_t) tv.tv_sec, (uint32_t) tv.tv_usec);
}
What this do it combine 32 bit timestamp, and 32 bit "something", probably micro/nanoseconds into single 64 bit integer.
I have really hard time to rewrite it with C++11 chrono.
This is what I did so far, but I think this is wrong way to do it.
auto tse = std::chrono::system_clock::now().time_since_epoch();
auto dur = std::chrono::duration_cast<std::chrono::nanoseconds>( tse ).count();
uint64_t time = static_cast<uint64_t>( dur );
Important note - I only care about first 32 bit to be "valid" timestamp.
Second 32 bit "part" can be anything - nano or microseconds - everything is good as long as two sequential calls of this function give me different second "part".
i want seconds in one int, milliseconds in another.
Here is code to do that:
#include <chrono>
#include <iostream>
int
main()
{
auto now = std::chrono::system_clock::now().time_since_epoch();
std::cout << now.count() << '\n';
auto s = std::chrono::duration_cast<std::chrono::seconds>(now);
now -= s;
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now);
int si = s.count();
int msi = ms.count();
std::cout << si << '\n';
std::cout << msi << '\n';
}
This just output for me:
1447109182307707
1447109182
307
The C++11 chrono types use only one number to represent a time since a given Epoch, unlike the timeval (or timespec) structure which uses two numbers to precisely represent a time. So with C++11 chrono you don't need the combine() method.
The content of the timestamp returned by now() depends on the clock you use; there are tree clocks, described in http://en.cppreference.com/w/cpp/chrono :
system_clock wall clock time from the system-wide realtime clock
steady_clock monotonic clock that will never be adjusted
high_resolution_clock the clock with the shortest tick period available
If you want successive timestamps to be always different, use the steady clock:
auto t1 = std::chrono::steady_clock::now();
...
auto t2 = std::chrono::steady_clock::now();
assert (t2 > t1);
Edit: answer to comment
#include <iostream>
#include <chrono>
#include <cstdint>
int main()
{
typedef std::chrono::duration< uint32_t, std::ratio<1> > s32_t;
typedef std::chrono::duration< uint32_t, std::milli > ms32_t;
s32_t first_part;
ms32_t second_part;
auto t1 = std::chrono::nanoseconds( 2500000000 ); // 2.5 secs
first_part = std::chrono::duration_cast<s32_t>(t1);
second_part = std::chrono::duration_cast<ms32_t>(t1-first_part);
std::cout << "first part = " << first_part.count() << " s\n"
<< "seconds part = " << second_part.count() << " ms" << std::endl;
auto t2 = std::chrono::nanoseconds( 2800000000 ); // 2.8 secs
first_part = std::chrono::duration_cast<s32_t>(t2);
second_part = std::chrono::duration_cast<ms32_t>(t2-first_part);
std::cout << "first part = " << first_part.count() << " s\n"
<< "seconds part = " << second_part.count() << " ms" << std::endl;
}
Output:
first part = 2 s
seconds part = 500 ms
first part = 2 s
seconds part = 800 ms

Add time duration to C++ timepoint

I have a starting timepoint in milliseconds like so:
using namespace std::chrono;
typedef time_point<system_clock, milliseconds> MyTimePoint;
MyTimePoint startTimePoint = time_point_cast<MyTimePoint::duration>(system_clock::time_point(steady_clock::now()));
Now I will have a certain number of hours that I want to add or subtract to the startTimePoint.
int numHours = -5//or 5 etc (Can be a plus or minus number)
How can I add this abount of time to the original startTimePoint??
If you want to add five hours to startTimePoint, it's boringly simple:
startTimePoint += hours(5); // from the alias std::chrono::hours
Live example.
By the way, you're trying to convert a steady_clock::now() into a system_clock::time_point, which shouldn't even compile. Change the steady_clock::now() to system_clock::now() and you should be good to go.
Here I have used time in minutes you can go for anything that you want from the user.
So the below is the simple programme using chrono
#include <iostream>
#include <chrono>
using namespace std;
int main() {
using clock = std::chrono::system_clock;
clock::time_point nowp = clock::now();
cout<<"Enter the time that you want to add in minutes"<<endl;
int time_min;
cin>>time_min;
cin.ignore();
clock::time_point end = nowp + std::chrono::minutes(time_min);
time_t nowt = clock::to_time_t ( nowp );
time_t endt = clock::to_time_t ( end);
std::cout << " " << ctime(&nowt) << "\n";
std::cout << ctime(&endt) << std::endl;
return 0;
}
Convert time_point to duration or duration to time_point without intermediate.
It is inherently impossible to convert a time_point to duration or back directly.
Many examples use time_t as intermediate, which is a fine method.
I use the method that uses the time_point 'zero' as a helper.
#include <iostream>
#include <chrono>
#include <thread>
using namespace std;
int main(int argc, char *argv[])
{
using namespace std::chrono;
system_clock::time_point zero; // initialised to zero in constructor
system_clock::time_point tp_now; // now as time_point
duration<int, ratio<1>> dur_now; // now as duration
system_clock::time_point tp_future; // calculated future as time_point
// The objective is to sleep_until the system time is at the next 5 minutes
// boundary (e.g. time is 09:35)
tp_now = system_clock::now(); // What time is it now?
cout << "tp_now = " << tp_now.time_since_epoch().count() << endl;
// It is not possible to assign a time_point directly to a duration.
// but the difference between two time_points can be cast to duration
dur_now = duration_cast<seconds>(tp_now-zero); // subtract nothing from time_point
cout << "dur_now = " << dur_now.count() << endl;
// Instead of using seconds granularity, I want to use 5 minutes
// so I define a suitable type: 5 minutes in seconds
typedef duration<int,ratio<5*60>> dur5min;
// When assigning the time_point (ok: duration) is truncated to the nearest 5min
dur5min min5 = duration_cast<dur5min>(tp_now-zero); // (Yes, I do it from time_point again)
cout << "min5 ('now' in 5min units) = " << min5.count() << endl;
// The next 5 min time point is
min5 += dur5min{1};
cout << "min5 += dur5min{1} = " << min5.count() << endl;
// It is not possible to assign a duration directly to a time_point.
// but I can add a duration to a time_point directly
tp_future = zero + min5;
cout << "tp_future = " << tp_future.time_since_epoch().count() << endl;
// to be used in e.g. sleep_until
// std::this_thread::sleep_until(tp_future);
return 0;
}
Thanks to Carsten's solution I managed to create function:
#include <chrono>
auto getTimeDurationMovedWith(std::chrono::hours hours2move)
{
using namespace std::chrono;
auto current_time = system_clock::now();
decltype(current_time) zeroTime; // no better solution to move time found in stackoverflow
return chrono::duration_cast<microseconds>(
current_time - zeroTime + hours(hours2move));
}
And it can be used like that:
auto tmp = getTimeDurationMovedWith(chrono::hours(-10));
cout << tmp.count() << endl;