Time points

Epoch

A point in time is represented as a duration between a specific moment (Used as reference), called epoch, and the time point represented. For example, we represent dates with the year 1 as reference: The year 2000 is 1999 years after the year 1 (1 A.D.) and the year -500 (500 B.C.) is 499 years before the year (1 B.C.). The year 1 (1 A.D.) is the epoch used to represent dates with positive years and the year -1 (1 B.C.) is the epoch for dates with a negative year. For those who do not know, the Gregorian calendar starts at the year 1 (1 A.D.) and not 0, so the year 2000 is 1999 years after its epoch.

The class time_point

The class std::chrono::time_point<class C, class D = C::duration> is used to represent an exact moment in time (Example, the moment you first started learning C/C++).

The C++ Standard Library defines 3 types of clocks used to retrieve time points, and each of them may use a different epoch. Those clocks have a static method called now that returns an object of type std::chrono::time_point representing the time elapsed between right now and the epoch they use.

The first template argument of the class std::chrono::time_point is the clock type (Used to define the epoch of the time point) and the second one is the std::chrono::duration type used to represent the time elapsed between the epoch and the moment represented.

The 3 clocks are named system_clock, steady_clock and high_resolution_clock. They may all use different std::chrono::duration types. Their method now returns an object of type std::chrono::time_point, with, as template arguments, the type of the clock and the std::chrono::duration type they use.

To retrieve a time point returned by a clock, we must assign it to a time_point object of the same type (Or convert it). By default, the second template argument of the class std::chrono::time_point is set to the std::chrono::duration type used by the clock type given as first template argument.

Alternatively, we can use the type time_point defined in the namespace of the clock used, which is a typedef of the std::chrono::time_point type its method now returns.

We can retrieve the duration between the epoch and the moment represented by a time_point object by using its method duration std::chrono::time_point::time_since_epoch() const.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream> #include <chrono> int main() { std::chrono::time_point<std::chrono::system_clock> timePoint1 = std::chrono::system_clock::now(); /* Or */ // std::chrono::system_clock::time_point timePoint1 = std::chrono::system_clock::now(); std::chrono::time_point<std::chrono::steady_clock> timePoint2 = std::chrono::steady_clock::now(); /* Or */ // std::chrono::steady_clock::time_point timePoint2 = std::chrono::steady_clock::now(); std::chrono::time_point<std::chrono::high_resolution_clock> timePoint3 = std::chrono::high_resolution_clock::now(); /* Or */ // std::chrono::high_resolution_clock::time_point timePoint3 = // std::chrono::high_resolution_clock::now(); std::cout << "system_clock: " << timePoint1.time_since_epoch().count() << " periods elapsed since the epoch.\n\n"; std::cout << "steady_clock: " << timePoint2.time_since_epoch().count() << " periods elapsed since the epoch.\n\n"; std::cout << "high_resolution_clock: " << timePoint3.time_since_epoch().count() << " periods elapsed since the epoch.\n\n"; return 0; }

Operations with time points as operands

We can use the assignment, mathematical and logical operators with objects of type std::chrono::time_point as operands. The operands can be of different time_point types (But the clock type must be the same). In that case, they are automatically converted for the operation. Note that subtracting a time_point object from an other time_point object returns an object of type duration representing the (Positive of negative) duration between the two time points.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream> #include <chrono> int main() { std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now(); // Executes some instructions for(unsigned c = 0; c < 10 * 1000 * 1000; c++) {} std::chrono::steady_clock::duration nbPeriodsElapsed = std::chrono::steady_clock::now() - start; std::cout << nbPeriodsElapsed.count() << " periods of " << std::chrono::steady_clock::duration::period::num << '/' << std::chrono::steady_clock::duration::period::den << " seconds elapsed.\n"; return 0; }

Converting (Casting) time point types

Using the function time_point_cast, we can convert time_point objects to time_point objects of different types (With a different duration type).

It takes, in argument, the time_point object to convert and it takes, in template argument, the duration type the time_point type, to convert to, uses. It returns the converted time_point.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream> #include <chrono> // typedef named 'days' of a duration type using a period of 1 day. typedef std::chrono::duration<unsigned long, std::ratio<3600 * 24>> days; int main() { // Retrieves the current time point as an object of the time_point type used by system_clock. std::chrono::system_clock::time_point sysTimeP = std::chrono::system_clock::now(); // Converts the time_point object retrieved into a time_point object using a period of 1 day. std::chrono::time_point<std::chrono::system_clock, days> nbDays = std::chrono::time_point_cast<days>(sysTimeP); // Retrieves the number of periods (Of 1 day) elapsed since the epoch used by system_clock. std::cout << nbDays.time_since_epoch().count(); std::cout << " days since the epoch used by system_clock.\n"; return 0; }

Note that time_point type casting may lead, in the same cases as duration type casting, to precision or data loss.