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;.
#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:
2min + 30sadds minutes to seconds. The sum gets the type of the finer of the two units, that is, seconds, andtotalholds150seconds.std::chrono::milliseconds ms = total;converts the seconds to milliseconds:150000..count()returns each duration's number of units, and the program prints150 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:
std::chrono::milliseconds ms{1500};
std::chrono::seconds s = ms; // ✗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,500msand2minwork afterusing namespace std::chrono_literals;. - A duration converts to finer units by itself, and to coarser ones only through
duration_cast. duration_castrounds toward zero:1500msbecomes1s.
Subscribe to take the course
The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.