How to convert std::chrono::high_resolution_clock::now() to milliseconds, microseconds, ...?
Asked Answered
F

3

12

I got this code from How to get duration, as int milli's and float seconds from <chrono>?

#include <chrono>
#include <iostream>

int main (int argc, char *argv[])
{
  auto t0 = std::chrono::high_resolution_clock::now();
  auto t1 = std::chrono::high_resolution_clock::now();

  std::chrono::duration< double > fs = t1 - t0;
  std::chrono::milliseconds d = std::chrono::duration_cast< std::chrono::milliseconds >( fs );

  std::cout << fs.count() << "s\n";
  std::cout << d.count() << "ms\n";
}

Which works perfectly, but how I can create a time stamp with:

hour:minute:second:millisecond:microsecond:nanosecond

Using the auto t0 = std::chrono::high_resolution_clock::now() value?

I tried to print the auto t0 = std::chrono::high_resolution_clock::now(); value, to see what it had inside, however it only gave me a big error stack:

#include <chrono>
#include <iostream>

int main (int argc, char *argv[])
{
  auto t0 = std::chrono::high_resolution_clock::now();
  std::cout << t0 << "\n";
}

Error:

main2.cpp: In function 'int main(int, char**)':
main2.cpp:10:13: error: no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and 'std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long long int, std::ratio<1, 1000000000> > >')
   std::cout << t0 << "\n";
   ~~~~~~~~~~^~~~~
Faena answered 3/3, 2018 at 23:31 Comment(3)
std::chrono::microseconds(fs).count()??Martres
In the first example you use the std::duration::count member function. Why don't you use it in the second example?Callery
You should probably learn about std::put_time as well.Callery
P
5

You can print a chrono::timepoint like this:

auto t0 = std::chrono::high_resolution_clock::now();        
auto nanosec = t0.time_since_epoch();

std::cout << nanosec.count() << " nanoseconds since epoch\n";
std::cout << nanosec.count() / (1000000000.0 * 60.0 * 60.0) << " hours since epoch\n";
Permafrost answered 4/3, 2018 at 3:15 Comment(1)
you should not divide by all this numbers yourself, you need to use duration_cast to std::chrono::hours or std::chrono::duration<float, std::chrono::hours::period>Ma
F
6

Thanks to @Miles Budnek comment, I cannot use high_resolution_clock because it does not measure time, but CPU ticks. So, I found this answer based on Print current system time in nanoseconds using c++ chrono to do it the best.

#include <chrono>
#include <ctime>
#include <time.h>
#include <iostream>

// C++ -> Numerics library -> Compile time rational arithmetic -> std::ratio
// http://en.cppreference.com/w/cpp/numeric/ratio/ratio
//
// How to convert std::chrono::high_resolution_clock::now() to milliseconds, microseconds, ...?
// https://mcmap.net/q/932759/-how-to-convert-std-chrono-high_resolution_clock-now-to-milliseconds-microseconds
int main (int argc, char *argv[])
{
  std::chrono::time_point< std::chrono::system_clock > now = std::chrono::system_clock::now();
  auto duration = now.time_since_epoch();

  /* UTC: -3:00 = 24 - 3 = 21 */
  typedef std::chrono::duration< int, std::ratio_multiply< std::chrono::hours::period, std::ratio< 21 > >::type > Days;

  Days days = std::chrono::duration_cast< Days >( duration );
  duration -= days;

  auto hours = std::chrono::duration_cast< std::chrono::hours >( duration );
  duration -= hours;

  auto minutes = std::chrono::duration_cast< std::chrono::minutes >( duration );
  duration -= minutes;

  auto seconds = std::chrono::duration_cast< std::chrono::seconds >( duration );
  duration -= seconds;

  auto milliseconds = std::chrono::duration_cast< std::chrono::milliseconds >( duration );
  duration -= milliseconds;

  auto microseconds = std::chrono::duration_cast< std::chrono::microseconds >( duration );
  duration -= microseconds;

  auto nanoseconds = std::chrono::duration_cast< std::chrono::nanoseconds >( duration );

  // C library function - localtime()
  // https://www.tutorialspoint.com/c_standard_library/c_function_localtime.htm
  //
  // struct tm {
  //    int tm_sec;         // seconds,  range 0 to 59
  //    int tm_min;         // minutes, range 0 to 59
  //    int tm_hour;        // hours, range 0 to 23
  //    int tm_mday;        // day of the month, range 1 to 31
  //    int tm_mon;         // month, range 0 to 11
  //    int tm_year;        // The number of years since 1900
  //    int tm_wday;        // day of the week, range 0 to 6
  //    int tm_yday;        // day in the year, range 0 to 365
  //    int tm_isdst;       // daylight saving time
  // };

  time_t theTime = time(NULL);
  struct tm *aTime = localtime(&theTime);

  std::cout << days.count() << " days since epoch or "
            << days.count() / 365.2524 << " years since epoch. The time is now "
            << aTime->tm_hour << ":"
            << minutes.count() << ":"
            << seconds.count() << ":"
            << milliseconds.count() << ":"
            << microseconds.count() << ":"
            << nanoseconds.count() << std::endl;
}

Running it, outputs:

$ g++ -O0 -g -Wall -std=c++11 -o test timestamp_example.cpp && ./test
20107 days since epoch or 55.0496 years since epoch. The time is now 21:39:51:935:732:700
Faena answered 3/3, 2018 at 23:57 Comment(0)
P
5

You can print a chrono::timepoint like this:

auto t0 = std::chrono::high_resolution_clock::now();        
auto nanosec = t0.time_since_epoch();

std::cout << nanosec.count() << " nanoseconds since epoch\n";
std::cout << nanosec.count() / (1000000000.0 * 60.0 * 60.0) << " hours since epoch\n";
Permafrost answered 4/3, 2018 at 3:15 Comment(1)
you should not divide by all this numbers yourself, you need to use duration_cast to std::chrono::hours or std::chrono::duration<float, std::chrono::hours::period>Ma
V
4

I have a class that I use to do bench mark timing calculations that uses std::chrono. It is a class template that accepts a Resolution. Shown Here:

#ifndef EXECUTION_TIMER_H
#define EXECUTION_TIMER_H

#include <chrono>
#include <type_traits>
#include <sstream>
#include <iostream>

template <class Resolution = std::chrono::milliseconds>
class ExecutionTimer {
public:
    using Clock = std::conditional_t<std::chrono::high_resolution_clock::is_steady,
        std::chrono::high_resolution_clock,
        std::chrono::steady_clock>;

private:
    const Clock::time_point mStart = Clock::now();

public:
    ExecutionTimer() = default;
    ~ExecutionTimer() {
        const auto end = Clock::now();
        std::ostringstream strStream;
        strStream << "Destructor Elapsed: "
            << std::chrono::duration_cast<Resolution>(end - mStart).count()
            << std::endl;
        std::cout << strStream.str() << std::endl;
    }

    inline void stop() {
        const auto end = Clock::now();
        std::ostringstream strStream;
        strStream << "Stop Elapsed: "
            << std::chrono::duration_cast<Resolution>(end - mStart).count()
            << std::endl;
        std::cout << strStream.str() << std::endl;
    }
};

#endif // !EXECUTION_TIMER_H

Using the class is very simple as the driver program will demonstrate.

#include <vector>
#include <iostream>
#include <conio.h> // for _getch().

#include "ExecutionTimer.h"

void someFunc() {
    // Some Operations Just To Get Difference In Time
    std::vector<int> values;
    for ( unsigned int i = 0; i < 1000; i++ ) {
        values.push_back( i * 2 );
    }

    int printed = 0;
    for ( auto i : values ) {
        if ( printed % 10 == 0 ) {
            std::cout << "\n";
            std::cout << i << ", ";
        } else {
            std::cout << i << ", ";
        }
        printed++;
    }
    std::cout << std::endl;
}

int main() {

    ExecutionTimer<> timer; // Default = std::chrono::miliseconds
    someFunc();
    timer.stop();

    ExecutionTimer<std::chrono::microseconds> timer2;
    someFunc();
    timer2.stop();    

    _getch();
    return 0;
}

The class above is doing what I think is what you are asking for in some sort of way.

Now when looking at your code above particularly these lines here:

std::chrono::duration< double > fs = t1 - t0;
std::chrono::milliseconds d = std::chrono::duration_cast< std::chrono::milliseconds >( fs );

I believe that you are missing the .count(); after passing in the value to the duration_cast<>.

Taking the above class and converting it to a timestamp struct or class shouldn't be all to difficult.

Venavenable answered 4/3, 2018 at 0:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.