Random Numbers, Dates and Times
The <random> library generates random numbers properly — with a choice of engine and distribution — and <chrono> handles durations, clocks, dates and time zones with types that make unit mistakes impossible.
Random numbers
Random generation has two parts: an engine that produces raw random bits, and a distribution that shapes them into the numbers you want:
#include <iostream> #include <random> int main() { std::random_device seed_source; // non-deterministic seed from the OS std::mt19937 engine{seed_source()}; // Mersenne Twister engine std::uniform_int_distribution<int> die{1, 6}; std::uniform_real_distribution<double> unit{0.0, 1.0}; std::normal_distribution<double> height{170.0, 8.0}; // mean 170, std. deviation 8 for (int i = 0; i < 5; ++i) std::cout << die(engine) << ' '; std::cout << '\n' << unit(engine) << ' ' << height(engine) << '\n'; }
Create the engine once and reuse it — creating a new engine for every number is slow and less random. The old C rand() has poor quality and a small range; prefer <random>.
Reproducible sequences
Seeding with a fixed number gives the same sequence every time — ideal for tests, simulations and games with replayable levels. The engines' raw output is specified exactly by the standard:
#include <iostream> #include <random> int main() { std::mt19937 engine{42}; for (int i = 0; i < 3; ++i) std::cout << engine() << ' '; std::cout << '\n'; }
1608637542 3421126067 4083286876
These three numbers are the same with every compiler. Distributions, however, are implemented differently by each standard library, so uniform_int_distribution results from a fixed seed can differ between GCC, Clang and MSVC. If you need identical results everywhere, derive values from the raw engine output yourself.
Shuffling and sampling
#include <algorithm> #include <iostream> #include <random> #include <string> #include <vector> int main() { std::mt19937 engine{std::random_device{}()}; std::vector<std::string> deck{"A", "K", "Q", "J", "10", "9"}; std::shuffle(deck.begin(), deck.end(), engine); for (const auto& c : deck) std::cout << c << ' '; std::cout << '\n'; }
None of these generators are suitable for passwords or security tokens — use your operating system's cryptographic random source or a crypto library for that.
Durations
<chrono> represents time spans as durations with units in their type, so mixing seconds and milliseconds can't go wrong:
#include <chrono> #include <iostream> int main() { using namespace std::chrono_literals; auto film = 2h + 15min; auto ad_break = 90s; auto total = film + ad_break; // converted automatically std::cout << total << '\n'; std::cout << std::chrono::duration_cast<std::chrono::minutes>(total) << '\n'; std::cout << std::chrono::duration<double, std::ratio<3600>>(total).count() << " hours\n"; }
8190s 136min 2.275 hours
Conversions that don't lose precision happen implicitly; those that would (seconds to minutes) need duration_cast.
Measuring elapsed time
steady_clock never jumps backwards, so it's the right clock for timing code:
#include <chrono> #include <iostream> int main() { auto start = std::chrono::steady_clock::now(); long long sum = 0; for (int i = 0; i < 50'000'000; ++i) sum += i % 7; auto elapsed = std::chrono::steady_clock::now() - start; std::cout << sum << " computed in " << std::chrono::duration_cast<std::chrono::milliseconds>(elapsed) << '\n'; }
For wall-clock time ("what time is it?"), use system_clock::now().
Calendar dates
C++20 adds calendar types: years, months, days, weekdays and dates, with checked arithmetic and formatting:
#include <chrono> #include <format> #include <iostream> int main() { using namespace std::chrono; year_month_day launch{year{2026}, October, day{8}}; sys_days launch_day = launch; std::cout << std::format("{:%A %d %B %Y}\n", launch_day); std::cout << "30 days later: " << year_month_day{launch_day + days{30}} << '\n'; auto christmas = sys_days{2026y / December / 25}; std::cout << (christmas - launch_day).count() << " days until Christmas\n"; year_month_day bad{year{2026}, February, day{30}}; std::cout << std::boolalpha << "2026-02-30 valid? " << bad.ok() << '\n'; std::cout << "2028 is a leap year? " << year{2028}.is_leap() << '\n'; }
Thursday 08 October 2026 30 days later: 2026-11-07 78 days until Christmas 2026-02-30 valid? false 2028 is a leap year? true
C++20 also includes time-zone support (std::chrono::zoned_time), though not every standard library implements it fully yet.
Try it yourself
Work out how old someone is in days and which weekday they were born on.
Born on a Sunday, 10070 days ago (about 27 years)