I usually seed my RNG by the following time, obtained by a call to time.h
#include <iostream>
#include <time.h>
using namespace std;
int main()
{
cout << static_cast<unsigned int>(time(0)) << endl;
return 0;
}
Is there an equivalent to static_cast<unsigned int>(time(0)) in the Boost-library?
You can get the time using boost::posix_time. See this SO question. Ex:
boost::posix_time::time_duration diff = tick - now;
diff.total_milliseconds();
You can also use the C++11 chrono, if you can use C++11. Ex:
int elapsed_milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(end-start).count();
With these two methods, you can get the number of milliseconds from the start of the day, and then assign it to your seed.
Related
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();
}
So right now, the code im using is
using std::chrono::system_clock;
std::time_t tt = system_clock::to_time_t (system_clock::now());
struct std::tm * ptm = std::localtime(&tt);
std::cout << "Current time: " << std::put_time(ptm,"%X") << '\n';
std::this_thread::sleep_for (std::chrono::seconds(7));
It is simple in that this is in a loop, and chrono sleep_for delays the system for however many seconds.
The problem is that it is in the HH:MM:SS format when I really need seconds.milliseconds to show the system clock transaction time. How would I do this? I really just need someone to explain the code, why is it making a struct? And what should I do to change the format? Thanks!
I've got two answers for you:
How to do this next year (in C++20), which isn't implemented today, and
How you can do it today with some minor syntax changes and an open-source 3rd party library.
First 1:
#include <chrono>
#include <iostream>
#include <thread>
int
main()
{
using namespace std::chrono;
auto tp = system_clock::now();
while (true)
{
zoned_time zt{current_zone(), floor<milliseconds>(system_clock::now())};
cout << "Current time: " << std::format("{:%T}", zt) << '\n';
tp += 7s;
std::this_thread::sleep_until (tp);
}
}
This creates a local time using the computer's currently set time zone, with a precision of milliseconds. And then just prints it out with the desired format (%T). I'm using sleep_until instead of sleep_for so that each iteration of the loop doesn't drift off of the desired 7s interval due to loop overhead.
Second 2:
Nobody has C++20 chrono yet, but you can approximate it today with Howard Hinnant's free open source date/time library:
#include "date/tz.h"
#include <chrono>
#include <iostream>
#include <thread>
int
main()
{
using namespace date;
using namespace std::chrono;
auto tp = system_clock::now();
while (true)
{
zoned_time zt{current_zone(), floor<milliseconds>(system_clock::now())};
cout << "Current time: " << format("%T", zt) << '\n';
tp += 7s;
std::this_thread::sleep_until (tp);
}
}
The difference is that the format statement is slightly different, and the library lives in namespace date instead of namespace std::chrono. And there's an extra header to include. And some installation is required to handle the time zones.
If you're happy with a UTC time stamp, instead of a local time stamp, then you can use a header-only version of the same library like this (no installation required):
#include "date/date.h"
#include <iostream>
#include <thread>
int
main()
{
auto tp = std::chrono::system_clock::now();
while (true)
{
using namespace date;
using namespace std::chrono;
std::cout << "Current time: "
<< format("%T", floor<milliseconds>(system_clock::now())) << '\n';
tp += 7s;
std::this_thread::sleep_until (tp);
}
}
I have a uint64_t representing the number of nanoseconds since midnight. Would std::chrono allow me to convert this into a meaningful "time", relatively simply?
Also, how would I do it if I have the time since epoch?
For example in such a format:
14:03:27.812374923
And same situation, but when given nanoseconds since epoch? (in case the answer is significantly different)
You could use Howard Hinnant's, free, open-source, header-only library to do this:
#include "date.h"
#include <cstdint>
#include <iostream>
int
main()
{
using namespace std;
using namespace std::chrono;
using namespace date;
uint64_t since_midnight = 50607812374923;
cout << make_time(nanoseconds{since_midnight}) << '\n';
uint64_t since_epoch = 1499522607812374923;
cout << sys_time<nanoseconds>{nanoseconds{since_epoch}} << '\n';
}
This outputs:
14:03:27.812374923
2017-07-08 14:03:27.812374923
Or did you need to take leap seconds into account for since_epoch?
cout << utc_time<nanoseconds>{nanoseconds{since_epoch}} << '\n';
2017-07-08 14:03:00.812374923
For this latter computation, you'll need "tz.h" documented here, and this library is not header only.
I try to find a thread-safe way to get local time. From boost example, I got this:
#include "boost/date_time/posix_time/posix_time.hpp"
#include <iostream>
int
main()
{
using namespace boost::posix_time;
using namespace boost::gregorian;
//get the current time from the clock -- one second resolution
ptime now = second_clock::local_time();
//Get the date part out of the time
date today = now.date();
date tommorrow = today + days(1);
ptime tommorrow_start(tommorrow); //midnight
//iterator adds by one hour
time_iterator titr(now,hours(1));
for (; titr < tommorrow_start; ++titr) {
std::cout << to_simple_string(*titr) << std::endl;
}
time_duration remaining = tommorrow_start - now;
std::cout << "Time left till midnight: "
<< to_simple_string(remaining) << std::endl;
return 0;
}
But I didn't know if it can be used in multi-threading environment?
Yes, of your platform has support for it:
Date-time now uses reentrant POSIX functions on those platforms that support them when BOOST_HAS_THREADS is defined.
From here
BOOST_HAS_THREADS is basically always defined these days. You can check your platform's POSIX support if you doubt things.
I've tried a couple methods to print out time from the system_clock but I can't get anything other than whole seconds:
system_clock::time_point now = system_clock::now();
std::time_t now_c = system_clock::to_time_t(now);
std::cout<<ctime(&now_c);
std::cout<<std::put_time(std::localtime(&now_c), "%T")<<" ";
Does the now() function actually hold high precision data, or is that I just can't find the function that extracts that information for printing?
Note: I am not looking to calculate a time interval. I want the current time with fractions of a second, and to print it out via cout. I just can't find a way to do this.
And I know about std::chrono::high_resolution_clock but also see no way to print out its now(). Additionally, the setprecision function has no effect on the output of put_time or ctime.
I've been getting answers that do not actually address this question.
You can do the following:
#include <chrono>
#include <ctime>
#include <iostream>
#include <string>
std::string GetLocalTime() {
auto now(std::chrono::system_clock::now());
auto seconds_since_epoch(
std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()));
// Construct time_t using 'seconds_since_epoch' rather than 'now' since it is
// implementation-defined whether the value is rounded or truncated.
std::time_t now_t(
std::chrono::system_clock::to_time_t(
std::chrono::system_clock::time_point(seconds_since_epoch)));
char temp[10];
if (!std::strftime(temp, 10, "%H:%M:%S.", std::localtime(&now_t)))
return "";
return std::string(temp) +
std::to_string((now.time_since_epoch() - seconds_since_epoch).count());
}
int main() {
std::cout << GetLocalTime() << '\n';
return 0;
}
The existing answer is great, but it misses the leading zeros on the fractional part of the seconds, so 21:10:30.01 would be returned as 21:10:30.1
I don't have the rep to comment and my edit was rejected, so here's a fixed version:
#include <chrono>
#include <ctime>
#include <iostream>
#include <string>
std::string GetLocalTime() {
auto now(std::chrono::system_clock::now());
auto seconds_since_epoch(
std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()));
// Construct time_t using 'seconds_since_epoch' rather than 'now' since it is
// implementation-defined whether the value is rounded or truncated.
std::time_t now_t(
std::chrono::system_clock::to_time_t(
std::chrono::system_clock::time_point(seconds_since_epoch)));
char temp[10];
if (!std::strftime(temp, 10, "%H:%M:%S.", std::localtime(&now_t)))
return "";
std::string nanoseconds = std::to_string(
(std::chrono::duration<long long, std::nano>(
now.time_since_epoch() - seconds_since_epoch)).count());
return std::string(temp) + std::string(9-nanoseconds.length(),'0') + nanoseconds;
}
int main() {
std::cout << GetLocalTime() << '\n';
return 0;
}
Try std::chrono::high_resolution_clock.
(I think its c++11 only)