Cast chrono::milliseconds to uint64_t?

12,181

Solution 1

First of all, you generally shouldn't do this sort of thing. <chrono> provides a type-safe and generic units library for handling time durations, and there are few good reasons to escape this safety and genericity.

Some examples of the ills that don't happen with a type-safe, generic units library and which do happen with type-unsafe integral types:

// a type-safe units library prevents these mistakes:
int seconds = ...
int microseconds = seconds * 1000; // whoops
int time = seconds + microseconds; // whoops

void bar(int seconds);

bar(microseconds); // whoops

// a generic duration type prevents the need for:
unsigned sleep(unsigned seconds);
int usleep(useconds_t useconds);
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);

int attosleep(long long attoseconds); // ???

// just use:
template<typename Duration>
int sleep_for(Duration t); // users can specify sleep in terms of hours, seconds, microseconds, femetoseconds, whatever. Actual sleep duration depends on QoI, as always.

An example of a good reason would be compatibility with a third party library that made the unfortunate decision not to use a type-safe, generic units library in their API. In this case the conversions should be done as close as possible to the API boundary in order to minimize the extent to which unsafe types are used.


So with that said, when you do have a good reason, you do so like this:

std::chrono::milliseconds x = ...
std::uint64_t num = x.count();

Keep in mind that the predefined chrono durations such as chrono::milliseconds use signed representations, so you'll need to take care to ensure the value is appropriate for conversion to uint64_t.

Solution 2

The prototype for std::chrono::duration_cast is:

template <class ToDuration, class Rep, class Period>
constexpr ToDuration duration_cast(const duration<Rep,Period>& d);

You can't get an uint64_t directly, because it converts durations (duration_cast). So you need to create a std::duration with std::uint64_t.

using cast = std::chrono::duration<std::uint64_t>;
std::uint64_t ticks = std::chrono::duration_cast< cast >(something).count();
Share:
12,181

Related videos on Youtube

user997112
Author by

user997112

Updated on June 05, 2022

Comments

  • user997112
    user997112 almost 2 years

    Assuming I have the number of milliseconds in variable x:

    chrono::milliseconds x = std::chrono::duration_cast<chrono::milliseconds>(something);
    

    how do I convert x from chrono::milliseconds to uint64_t?

    I have tried:

    uint64_t num = std::chrono::duration_cast<uint64_t>(x);
    

    but it says:

    no matching function for call to duration_cast(std::chrono::milliseconds&)

  • user997112
    user997112 about 9 years
    Would duration_cast handle the unsigned cast to uint64_t?
  • bames53
    bames53 about 9 years
    @user997112 It would do the cast, but it won't do anything special to protect from overflow errors, or casting negative values to large unsigned values.