C++11 introduces the <chrono> library helpful to work with time spans. In this post, I go through its most important parts and show some examples.

Durations

Duration is the simplest type comprising of a ratio (e.g. 1:1000 for milliseconds) and the number of ticks. A single object is guaranteed to hold a timespan nearing 300 years.

You can implicitly cast values to more precise types, and there’s duration_cast<> to handle unsafe casting to more general ones. Duration supports basic arithmetics, so you can quickly add durations, multiply them, etc. Many of these operations will be evaluated at compilation time.

There are predefined durations, from an hour to a nanosecond. C++14 introduces duration literals, what makes it even easier to express timespans in code.

View the code on Gist.

$ clang++ -std=c++14 durations.cpp -o durations.exe && ./durations.exe 24h 1440min 86400s 86400000000ms 86400000000000ns 40min 3h + 52min + 40s - 2ns = 13959999999998ns

Clocks

We need the clock to get durations from the system. Chrono clock is a type containing some basic information: what type it returns, whether it is a stable clock (so that we avoid problems with system clock adjustments), and ability to get the current time.

The standard library provides three of them:

system_clock represents time as held by the system. It also provides to_time_t() method.

stable_clock is guaranteed to be monotonic

high_resolution_clock returns as precise time as possible

A clock returns a time point, from which we extract further information.

Time points

std::chrono::timepoint is a duration since the start of the epoch of the clock (Unix epoch is the de facto standard, at least for system_clock ). Every time point is associated with its clock and data from different ones is not interoperable.

Timepoints have basic algebra that returns durations. That makes it easy to calculate how long action took:

View the code on Gist.

$ clang++ -std=c++14 timepoints.cpp -o timepoints.exe && ./timepoints.exe Operation took: 277ms

Types Summary

Here’s a quick diagram showing how these things work together:

Get all the news! Did you like the content? You can get summaries regularly. A message or two per month. Also, try the social websites! First Name: Email address: Leave this field empty if you're human:

Example: simple game loop

We want to run input-update-render loop continuously, but it makes no sense to render scene trillion times a second since nobody would notice a change. Instead, loop allocates any free time to updates, so that game runs “no faster” than 60 frames per second.

View the code on Gist.

$ clang++ -std=c++14 gameloop.cpp -o gameloop.exe && ./gameloop.exe Loop: > updating... > updating... > updating... > updating... > updating... Loop: > updating... > updating... > updating... > updating... > updating... Loop: > updating... > updating... > updating... > updating... > updating... > updating...

Notice, that the third frame could squash one update more in 16ms.

View the code on Gist.

Notice that timestamps could be different since there are two separate time reads in the code:

$ clang++ -std=c++14 unixtimestamp.cpp -o unixtimestamp.exe && ./unixtimestamp.exe std::chrono only: 1492084951 with std::ctime: 1492084951

Unfortunately, our library does not support dates out of the box. That is by design (I think I saw some official explanation for this, will update when I recall the place). Good news is, Howard Hinnant wrote an excellent date library (GitHub).

See also