I have a double value that represents an epoch time but added the accuracy of a micro second. So a number like this:
double time_us=1628517578.547;
std::chrono::time_point time(time_us);
The above code doesn't;t work as I am getting the following error:
no instance of constructor "time_point" matches the argument list
I need to do this conversion to get the millisecond of the day (number of Milliseconds that passed from the last night).
I plan to use the following code to get the required millisecond:
double sysTOH=time.hour*3600+time.min*60+time.sec+time.usec*1e-6;
What is the best way to achieve this?
std::chrono:: is a lot to write everywhere, so I'm going to assume:
using namespace std::chrono;
time_point is not a concrete type, it is a class template:
template<class Clock, class Duration = typename Clock::duration> class time_point;
This means that you have to supply at least the first template parameter, and in your case, it is best to supply the second as well.
Your input, time_ms, has type double, and represents a count of seconds. So start by creating a type that matches that description:
using ds = duration<double>;
ds is a duration with a rep of double and a period of ratio<1>.
Now it is handy to use a little of C++20 <chrono>. Don't worry, if you don't have C++20, there is a free, open-source, header-only preview of it that works with C++11/14/17.
sys_time<ds> time{ds{time_ms}};
sys_time is a type alias supplied by "date/date.h" for the type:
time_point<system_clock, duration<double>>
I.e. a time_point based on system_clock using your custom duration type ds (double-based seconds).
One first converts the raw double to double-based seconds, and then to a time_point based on those seconds.
Next, it is best to convert to an integral-based time_point to find the time since midnight. Your questions uses microseconds and milliseconds somewhat interchangeably. So I am going to assume milliseconds for everything. Change to microseconds if you need to.
auto tp = round<milliseconds>(time);
This takes the double-based time_point and converts it to an integral-based time_point that counts milliseconds. round is used to avoid round-off error associated with double-based representations. round is part of C++17 and later, but "date/date.h" will supply it for you in C++11/14.
The type of tp is time_point<system_clock, milliseconds>.
Next it is convenient to truncate tp to a precision of days:
auto td = floor<days>(tp);
floor is part of C++17 and later, but "date/date.h" will supply it for you in C++11/14. days is a day-precision duration. td is simply a count of days since the Unix epoch, and has type time_point<system_clock, days>.
One can also think of td as a time point to the beginning of the day. So one can subtract it from tp to get the "time of day", or "time since midnight" UTC:
auto tod = tp - td;
tod has type milliseconds is the value is the number of milliseconds since midnight UTC. If you need midnight defined by some time zone, then there's a little more work to do to take the UTC offset into account. Your question is vague on this point.
Putting it all together:
#include "date/date.h"
#include <chrono>
#include <iostream>
int
main()
{
using namespace date;
using namespace std::chrono;
double time_ms=1628517578.547;
using ds = duration<double>;
sys_time<ds> time{ds{time_ms}};
auto tp = round<milliseconds>(time);
auto td = floor<days>(tp);
auto tod = tp - td;
std::cout << "tod = " << tod << '\n';
}
Output:
tod = 50378547ms
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With