3

I'm trying to generate a timestamp with a resolution of a microsecond. I tried using this answer Extract year/month/day etc. from std::chrono::time_point in C++ and also this one: C++11 actual system time with milliseconds but I'm not sure that doing it right:

template <typename Duration>
void print_time(tm t, Duration fraction) {
using namespace std::chrono;
std::printf("[%04u-%02u-%02u %02u:%02u:%02u.%03u.%03u]\n", t.tm_year + 1900,
        t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec,
        static_cast<unsigned>(fraction / milliseconds(1)),
        static_cast<unsigned>(fraction / microseconds(1)));
}

int main() {
using namespace std;
using namespace std::chrono;
system_clock::time_point now = system_clock::now();
system_clock::duration tp = now.time_since_epoch();
tp -= duration_cast<seconds>(tp);
time_t tt = system_clock::to_time_t(now);
cout << tp.count() <<endl;
print_time(*gmtime(&tt), tp);
print_time(*localtime(&tt), tp);

and the output for this code is :

324760155 [2019-09-15 10:09:13.324.324760] [2019-09-15 10:09:13.324.324760]

Valentino
  • 7,291
  • 6
  • 18
  • 34
yaodav
  • 1,126
  • 12
  • 34

2 Answers2

2
template <typename Rep, typename Period>
void
print_time(tm t, std::chrono::duration<Rep, Period> fraction)
{
    using namespace std::chrono;
    auto ms = duration_cast<milliseconds>(fraction);
    fraction -= ms;
    auto us = duration_cast<microseconds>(fraction);
    std::printf("[%04u-%02u-%02u %02u:%02u:%02u.%03u.%03u]\n", t.tm_year + 1900,
        t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec,
        static_cast<unsigned>(ms / milliseconds(1)),
        static_cast<unsigned>(us / microseconds(1)));
}
  • The change I made to your parameter keeps it from being overly generic and accepting something that is not a chrono::duration.

  • To get the number of milliseconds out of fraction (and assuming fraction is non-negative), just duration_cast<milliseconds>(fraction).

  • Now you need to subtract the milliseconds obtained in the previous step out of fraction, lest they will come back to haunt you in the next step.

  • To get the number of microseconds out of fraction (and assuming fraction is non-negative), just duration_cast<microseconds>(fraction).

If you wanted to go further and get the nanoseconds out of fraction, you would need to first subtract the microseconds part out before proceeding.

Howard Hinnant
  • 206,506
  • 52
  • 449
  • 577
0

You are losing accuracy on this line:
tp -= duration_cast<seconds>(tp);
Get data in microseconds at once, and better in nanoseconds, and then re-read them in the desired format.

Silerus
  • 36
  • 6
  • now I'm getting [2019-09-15 10:46:00.881297578.829282533] what the mining of these numbers? – yaodav Sep 15 '19 at 10:50
  • this time in nanoseconds from January 1, 1970 to the current moment. i.e. UNIX time. But divided by millisecond (first number) and microsecond (second). The question is, what do you think should have been in the last numbers? Because if we needed a timestamp in seconds / milliseconds / microseconds / nanoseconds just like unix time? which can then be converted into a readable time by a standard function. What is written at the end of printf is superfluous, it was enough to get tp in the right format and that's it. – Silerus Sep 15 '19 at 11:16
  • my main goal is to measure to benchmark my program by comparing timestamp, so I want the time stamp to be like HH:MM:SS:ML:US – yaodav Sep 15 '19 at 11:23
  • 1
    We will go the other way:
    ```std::chrono::time_point start, end; std::chrono::system_clock::duration elapsed; start = std::chrono::system_clock::now(); /*main programm cicle*/ elapsed = std::chrono::duration_cast(end-start); //now we have the number of microseconds spent```
    Name the number of microseconds, we can divide them by the number of microseconds per hour, get hours / in a minute - get minutes / in a second. You just need to remember to subtract the result already obtained.
    – Silerus Sep 15 '19 at 12:05