Chrono and Formatting
Chrono and Formatting
Measure time correctly and produce readable output with modern formatting APIs.
Chrono and Formatting
Measure time correctly and produce readable output with modern formatting APIs.
Use std::chrono::steady_clock for elapsed time and timeouts. Use std::chrono::system_clock for timestamps that correspond to calendar time.
using namespace std::chrono_literals;
auto start = std::chrono::steady_clock::now();
do_work();
auto end = std::chrono::steady_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
steady_clock will not jump backwards if the system time changes.
That makes it the default choice for benchmarks, retries, and timeouts.
auto retry_delay = 250ms;
auto max_wait = 5s;
Duration literals remove the guesswork around raw integers.
using namespace std::chrono_literals;
if (elapsed > 2s) {
retry();
}
auto message = std::format("processed {} items in {} ms", count, elapsed.count());
std::cout << message << '\n';
This scales better than long stream chains once formatting becomes more structured.
If your standard library supports it, std::print can write directly:
std::print("processed {} items in {} ms\n", count, elapsed.count());
void benchmark_sort(std::vector<int> values) {
auto start = std::chrono::steady_clock::now();
std::ranges::sort(values);
auto end = std::chrono::steady_clock::now();
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::print("sorted {} values in {} ms\n", values.size(), ms.count());
}
class Stopwatch {
public:
void start() {
running_ = true;
started_at_ = std::chrono::steady_clock::now();
}
void stop() {
if (running_) {
elapsed_ += std::chrono::steady_clock::now() - started_at_;
running_ = false;
}
}
void reset() {
elapsed_ = std::chrono::steady_clock::duration::zero();
running_ = false;
}
auto elapsed_ms() const {
return std::chrono::duration_cast<std::chrono::milliseconds>(elapsed_);
}
private:
std::chrono::steady_clock::time_point started_at_{};
std::chrono::steady_clock::duration elapsed_{};
bool running_ = false;
};
This kind of helper is where chrono types become practical instead of abstract: you accumulate durations safely without falling back to raw integers.
auto now = std::chrono::system_clock::now();
auto stamp = std::format("{:%Y-%m-%d %H:%M}", now);
Use this when the output is meant for people rather than just internal timing.
using namespace std::chrono_literals;
auto deadline = std::chrono::steady_clock::now() + 250ms;
if (std::chrono::steady_clock::now() > deadline) {
retry();
}
Time points represent "when". Durations represent "how long". Most chrono code is cleaner once you keep those roles separate.
system_clock for elapsed-time measurementstd::cout << ... chain with std::format.#include <format>
#include <string>
int main() {
std::string text = std::format("value = {}", 42);
return static_cast<int>(text.size());
}
Swap one older pattern for a newer standard facility, then compare clarity. This keeps modern C++ grounded in practical tradeoffs instead of feature tourism.
#include <format>
#include <string>
int main() {
std::string line = std::format("{} items ready", 3);
return static_cast<int>(line.size());
}