Time and Random Numbers

Durations and Time Points

A duration is a number of ticks of some fixed period. A time point is a specific point in time related to the beginning of some clock. Together, these make up the basis of the chrono library.

It's easy to make a duration; you select a period and a count.

#include <iostream>
#include <chrono>

int main()
{
    std::chrono::milliseconds ms{ 1500 };
    std::cout << ms.count() << '\n';
}

ms is a duration object representing 1500 milliseconds. Calling count() just reveals this stored number of ticks, so it just prints 1500. The type itself has its own sense of a period; there's no further conversion needed to discover the base number.

Durations of different periods may be converted among themselves as long as either the conversion is exact or an explicit cast is used.

#include <iostream>
#include <chrono>

int main()
{
    std::chrono::seconds s{ 2 };
    std::chrono::milliseconds ms{ s };
    std::cout << ms.count() << '\n';
}

s contains 2 seconds. The initialization of ms shows how to convert it, automatically changing the period from seconds to milliseconds. Because 1 sec is exactly equal to 1000 milliseconds, the conversion is exact, and the count for ms is 2000. The actual conversion happens at compile time when the periods fit.

To get a time point, you can query a clock and get the current moment.

#include <iostream>
#include <chrono>

int main()
{
    // Represent a specific point on a clock timeline
    std::chrono::steady_clock::time_point tp{ std::chrono::steady_clock::now() };
    std::cout << tp.time_since_epoch().count() << '\n';
}

std::chrono::steady_clock::now() returns a time_point, which is stored in tp. Calling time_since_epoch() gives the duration elapsed since the start of the clock. count() then reveals the number of ticks since then, usually without immediate utility, but useful when you subtract this value from another time point later.

Subtracting two time points gives a duration.

#include <iostream>
#include <chrono>

int main()
{
    // Let the initializer determine this variable type
    auto start{ std::chrono::steady_clock::now() };
    auto end{ std::chrono::steady_clock::now() };
    auto diff{ end - start };
    std::cout << std::chrono::duration_cast<std::chrono::nanoseconds>(diff).count() << '\n';
}

Here, start and end both contain the current moment, at nearly the same time. Their difference, diff, is a very small duration. By calling duration_cast to convert to nanoseconds, we find out roughly how many ticks occurred, and count() outputs a readable integer.

You can also add a duration to a time point to get a later time point, which still retains the original clock. Arithmetic operations involving durations and time points are never able to cross clocks; subtracting or comparing time points from different clocks has undefined behavior.

Hence, a duration measures “how long,” a time_point measures “when,” and all interval measurements consist in capturing two time points and subtracting them to yield a duration.

0 comments

No comments yet. Be the first.

Add a comment

About CppLearn

CppLearn is an interactive, free reference for modern C++. In each lesson, you'll find out how the language works, rather than just lines of code that you can copy and paste. We cover concepts starting from beginner lessons on fundamentals and proceed to templates, move semantics, smart pointers, and areas that usually trap or scare C++ learners.