Skip to content
Theory · Multithreading: An Overview · lesson 11 of 12

Durations: chrono

A recipe says: boil for 2 minutes 30 seconds. The kitchen timer counts seconds, so the cook converts the time and sets 150. Mix up the units and set 150 minutes, and the soup boils away. A program also stores time together with its units, and mixing up units is a common mistake.

A thread often needs to wait: std::this_thread::sleep_for pauses it for a given duration. A duration is a number together with a unit. It is expressed with types from the <chrono> header:

  • std::chrono::minutes: minutes;
  • std::chrono::seconds: seconds;
  • std::chrono::milliseconds: thousandths of a second.

The .count() method returns the number of units. The literals 2min, 30s and 500ms are available after the line using namespace std::chrono_literals;.

C++
#include <chrono>
#include <iostream>

using namespace std::chrono_literals;

int main() {
    std::chrono::seconds total = 2min + 30s;
    std::chrono::milliseconds ms = total;
    std::cout << total.count() << ' ' << ms.count() << '\n';  // 150 150000
}

Let's go through main line by line:

  1. 2min + 30s adds minutes to seconds. The sum gets the type of the finer of the two units, that is, seconds, and total holds 150 seconds.
  2. std::chrono::milliseconds ms = total; converts the seconds to milliseconds: 150000.
  3. .count() returns each duration's number of units, and the program prints 150 150000.

To coarser units, explicitly

Converting units is like changing money. Dollars can always be changed into cents without loss. Cents go into dollars only with a remainder: 150 cents is one dollar, and the other 50 cents do not make a whole dollar.

Durations work the same way:

  • a duration converts to finer units by itself, since no precision is lost;
  • the opposite conversion can lose a fraction, so it is written explicitly, with std::chrono::duration_cast.

duration_cast rounds toward zero: std::chrono::duration_cast<std::chrono::seconds>(1500ms) equals 1s. This is where the money analogy ends: the leftover cents stay in your pocket, while duration_cast drops them without a trace.

Common mistake

Milliseconds are assigned to seconds:

C++
std::chrono::milliseconds ms{1500};
std::chrono::seconds s = ms;  // ✗
TEXT
error: no viable conversion from 'duration<[...], ratio<[...], 1000>>' to 'duration<[...], ratio<[...], 1>>'

This is a compile error: the program does not build. The message names std::chrono::milliseconds and std::chrono::seconds by their full types: ratio<…, 1000> is thousandths of a second, ratio<…, 1> whole seconds.

The compiler checks the types, not the value: converting milliseconds to seconds can lose a fraction, even if ms held exactly 2000. If the loss is acceptable, convert with duration_cast.

Key points

  • A duration is a number together with a unit: std::chrono::seconds, std::chrono::milliseconds, std::chrono::minutes; .count() returns the number of units.
  • The literals 30s, 500ms and 2min work after using namespace std::chrono_literals;.
  • A duration converts to finer units by itself, and to coarser ones only through duration_cast.
  • duration_cast rounds toward zero: 1500ms becomes 1s.

Subscribe to take the course

The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.

Sign in another way