Chrono Library in C++


In this article, we will learn about chrono library in C++. This library is used for managing date and time. As timer are different for different systems, so to bring precision we can use this library. The chrono library is also used to measure time elapsed during execution of a C++ program. It can measure the time in seconds, milli seconds , micro seconds and nano seconds.

Durations are the heart of the <chrono> library.

These six durations represent the convenient highlevel access:

  • hours
  • minutes
  • seconds
  • milliseconds
  • microseconds
  • nanoseconds

Good thing about this library is that it provides accurracy irrespective of machines.

Now lets consider about C++20 <chrono> becomes much easier to work with
because you can easily print values out, even without
knowing their type.

auto t0 = steady_clock::now();
...
auto t1 = steady_clock::now();
cout << "That took " << t1-t0 << '\n';

Output:

This will take 657s

Chrono Library defines mainly 3 types of utilities/functions:-

  1. Time Points
  2. Clocks
  3. Durations

1. Time Points

These are implemented by using specific time reference and calculating.Internally, the object stores an object of a duration type, and uses the Clock type as a reference for its (starting point)epoch.

Here let's see the template:

template<class Clock, class Duration = typename Clock::duration>
          class time_point;

So, we can that time_point is a wrapper around a duration.

  • These represent Same value and same representation but just a different
    meaning.

  • The time_point gives subset of arithmetic algebra so that we can catch logic errors at compile-time.

Example given below:

auto tt1 = system_clock::now(); // tt1 is a taken time_point
auto tt2 = system_clock::now(); // tt2 is a taken time_point
auto diff = tt2 - tp1; // diff is a duration
auto sum = tt2 + tt1; //this will give compile-time error

So, we can that in simple words that the time_point is templated can detect errors of mising time points from various available clocks

Example given below:

auto tt1 = system_clock::now(); // tt1 is a taken time_point
auto tt2 = steady_clock::now(); // tt2 is a taken time_point
auto diff = tt2 - tt1; // this will give compile-time error

2. Clocks

A clock defines an epoch and a tick period. For example, a clock might tick in milliseconds since the UNIX epoch (January 1, 1970) or tick in nanoseconds since the start of the program. In addition, a clock provides a type for any timepoint specified according to this clock.

SO, the interface of a clock provides a function now() to yield an object for the current point in
time.

i. system_clock :- It will show the current time of system.

ii.steady_clock :- Its a clock that can never be adjusted . It keeps on going.

iii. high_resolution_clock :- To increase the resolution i.e to avail samllest tick that would be possible.

Example of Count ticks:-

count ticks clock_t a, b;
a = clock ();
do_something_long (with , variables );
b = clock () - a;
printf (" took me %d clicks = %f seconds ",

3. Durations

The duration shows a duration/step of time, and can come in any unit.

It measures the time spans, like: one hour, two minutes, or five milliseconds.

Now let's see the template :

template<class Rep, class Period = ratio<1>>
class duration;

These Durations are represented by arithmetic type, else by a class type representing the arithmetic type.

• int, long, double, safe <int>, etc.

• duration::period is a compile-time fraction representing the time in seconds between each integral value stored in the duration.

template<class Rep, class Period = ratio<1>>
 class duration;
  • <chrono> defines several convenience type aliases for common units.

Existing Units

  • nanoseconds
  • microseconds
  • milliseconds
  • seconds
  • minutes
  • hours

New in c++20

  • days
  • weeks
  • months
  • years
//So, now we are going to represent in the integral representation of 10 milliseconds
std::chrono::duration<int, std::milli> d(10);
// c.count() == 12

c = std::chrono::milliseconds(5);
// c.count() == 50

c = std::chrono::seconds(10);
// c.count() == 1,000

Difference between time point and date

Now lets see the difference between time point and date:

  • The Time points can be taken to have arbitrarily fine precision.
  • The Time points can be taken to have arbitrarily coarse precision
  • And When the time point has a precision of a day, we call it a date.
  • All the precisions has a type in the chrono system.
time_point<system_clock, seconds>
time_point<system_clock, milliseconds>
time_point<system_clock, microseconds>
time_point<system_clock, nanoseconds>
time_point<system_clock, minutes>
time_point<system_clock, hours>
time_point<system_clock, days>
    
sys_time<Duration> is a type alias for time_point<system_clock, Duration>

sys_time<seconds>
sys_time<milliseconds>
sys_time<microseconds>
sys_time<nanoseconds>
sys_time<minutes>
sys_time<hours>
sys_time<days>

Just take a look above for the difference.

What is Calender ?

In simple words , the calendar is a collection of dates, where each date will be having a unique name.

When we have different calenders then Different calendars can refer to the same physical date, but have different names for that date.

sys_days is the canonical calendar in <chrono>

Let's start with The civil calender :

class year_month_day_last; data structure: {year, month}

This represents the last day of the {year, month} pair.

  • Constructible from a year and month.
  • Implicitly convertible to sys_days (it's a partial calendar).
  • Has year and month and day getters.
  • Equality and less-than comparable.
  • Does year and month-oriented arithmetic.

So , the Constructible with conventional syntax operators by replacing the day-specifier with last.

class year_month_day_last;
    
data structure: {year, month}
    
auto ymd = last/November/2019;
  • This is also Implicitly convertible to year_month_day.
year_month_day ymd = November/last/2019;

Time-Zone

Time-points can be displayed in various specific time-zones.

Due to the extended chrono library, the following use-cases are easy to implement:

Now we can represent the dates in various forms:

auto d1 = 2019y/oct/28;
auto d2 = 28d/oct/2019;
auto d3 = oct/28/2019; 

get the last day of a month
get the number of days between two dates
printing the current time in various time-zones

#include <iostream>
#include "date.h"
int main()
{
    using namespace date;
    using namespace std::chrono;
    auto now = system_clock::now();
    std::cout << "The current time is " << now << " UTC\n";
    auto current_year = year_month_day{floor<days>(now)}.year();
    std::cout << "The current year is " << current_year << '\n';
    auto h = floor<hours>(now) - sys_days{jan/1/current_year};
    std::cout << "It has been " << h << " since New Years!\n";
}

Chrono Library is not only a header , its also a namespace. All elements in Chrono header (except for the common_type specializations) are not defined directly under the std namespace (like most of the standard library) but under the std::chrono namespace.

C++ Example Code :

//Code Starts
    
#include <iostream>
#include <chrono>
#include <unistd.h>
using namespace std;

// C++ program to find the execution time of code
int main()
{
	auto start = chrono::steady_clock::now();//auto is used to auto assign the data type 

	cout<<"Let's Start"<<endl;
	sleep(5);

	auto end = chrono::steady_clock::now();

	cout << "Time Passed in nanoseconds : " 
		<< chrono::duration_cast<chrono::nanoseconds>(end - start).count()
		<< " ns" << endl;
    
	cout << "Time Passed  time in milliseconds : " 
		<< chrono::duration_cast<chrono::milliseconds>(end - start).count()
		<< " ms" << endl;

	cout << "Time Passed  time in seconds : " 
		<< chrono::duration_cast<chrono::seconds>(end - start).count()
		<< " sec";

	return 0;
}

OUTPUT OF CODE :

Time Passed in nanoseconds : 5000101816 ns
Time Passed  time in milliseconds : 5000 ms
Time Passed  time in seconds : 5 sec

Example 2:

// here we are going to find the time 
// taken by a function for execution of code
    
#include <iostream>    
#include <algorithm> 
#include <chrono> 
using namespace std; 
using namespace std::chrono; 

// To take an example we will fill up  a vector with random integers and then sort 
// them using the sort function present in stl . We fill record 
// and print the time required by sort function 
int main() 
{ 

	vector<int> values(1000000); 

	//It helps to Generate Random values 
	auto f = []() -> int { return rand() % 10000; }; 

	//here we are to Fill up the vector 
	generate(values.begin(), values.end(), f); 

	// now to Get starting timepoint 
	auto started = high_resolution_clock::now(); 

	// So, the Call the function, here sort() 
	sort(values.begin(), values.end()); 

	//Now let's mark the Get ending timepoint 
	auto ended = high_resolution_clock::now(); 

	// Get duration. Substart timepoints to 
	// get durarion. To cast it to proper unit 
	// use duration cast method 
	auto duration = duration_cast<microseconds>(ended - started); 

	cout << "Total Time taken by function: "
		<< duration.count() << " microseconds" << endl; 

	return 0; 
} 

Output Of Code :

Total Time taken by function: 512352 microseconds

With this article at OpenGenus, you must have got a complete idea of chrono library in C++ to handle time related data. Enjoy.