I use a library that uses the following struct to define a start timestamp as follows.
struct SYSTEMTIME {
/** year */
WORD year;
/** month */
WORD month;
/** day of week */
WORD dayOfWeek;
/** day */
WORD day;
/** hour */
WORD hour;
/** minute */
WORD minute;
/** second */
WORD second;
/** milliseconds */
WORD milliseconds;
};
For every log entry after this time is specified in nanoseconds difference from this first timestamp.
Lets say its UTC 2017-12-19 14:44:00 And the first following log entries are 397000ns after this.
How do I create a chronos, time_t or unix time from epoch from the first SYSTEMTIME struct and then add the nanoseconds to it.
Printout should be for this first entry 2017-12-19 14:44:00.000397
Best regards
Updated
I've slightly modified the code below to convert between SYSTEMTIME
and date::sys_time<std::chrono::milliseconds>
, instead of date::sys_time<std::chrono::nanoseconds>
.
Rationale: So that there is no implicit precision loss in to_SYSTEMTIME
. Clients of to_SYSTEMTIME
can explicitly truncate precision in any way that they desire (floor
, round
, ceil
, etc.). And failure to truncate precision (if needed) won't be a silent run time error.
The client code (in main
) is not impacted by this change.
You could use Howard Hinnant's free, open-source, header-only date/time library for this:
#include "date/date.h"
#include <iostream>
using WORD = int;
struct SYSTEMTIME {
/** year */
WORD year;
/** month */
WORD month;
/** day of week */
WORD dayOfWeek;
/** day */
WORD day;
/** hour */
WORD hour;
/** minute */
WORD minute;
/** second */
WORD second;
/** milliseconds */
WORD milliseconds;
};
date::sys_time<std::chrono::milliseconds>
to_sys_time(SYSTEMTIME const& t)
{
using namespace std::chrono;
using namespace date;
return sys_days{year{t.year}/t.month/t.day} + hours{t.hour} +
minutes{t.minute} + seconds{t.second} + milliseconds{t.milliseconds};
}
int
main()
{
using namespace std::chrono;
using namespace date;
SYSTEMTIME st{2017, 12, 2, 19, 14, 44, 0, 0};
auto t = to_sys_time(st) + 397000ns;
std::cout << floor<microseconds>(t) << '\n';
}
Output:
2017-12-19 14:44:00.000397
This converts a SYSTEMTIME
to a std::chrono::time_point<system_clock, milliseconds>
(which has a type-alias named date::sys_time<milliseconds>
) by collecting the different parts out of the SYSTEMTIME
. It then simply adds nanoseconds
to that time_point
, truncates it to the desired precision of microseconds
, and streams it out.
If it would be helpful, here is how you could use the same library to do the opposite conversion:
SYSTEMTIME
to_SYSTEMTIME(date::sys_time<std::chrono::milliseconds> const& t)
{
using namespace std::chrono;
using namespace date;
auto sd = floor<days>(t);
year_month_day ymd = sd;
auto tod = make_time(t - sd);
SYSTEMTIME x;
x.year = int{ymd.year()};
x.month = unsigned{ymd.month()};
x.dayOfWeek = weekday{sd}.c_encoding();
x.day = unsigned{ymd.day()};
x.hour = tod.hours().count();
x.minute = tod.minutes().count();
x.second = tod.seconds().count();
x.milliseconds = tod.subseconds().count();
return x;
}