Home > front end >  c : convert std::chrono of variable unit to seconds
c : convert std::chrono of variable unit to seconds

Time:10-26

Let's say I have a timeInterval parameter that's a std::chrono::duration, but of a non-predetermined unit size - sometimes it'll be std::chrono::seconds, sometimes std::chrono:milliseconds, who knows.

Let's say I have a float DamagePerSecond - to calculate the damage done over the time interval, I need to calculate the floating point value of the timeInterval in seconds, and just multiply them.

From a lot of Googling, viewing tutorials on YouTube, and viewing solutions on here, it seems that .count() gives whole number of seconds.

Ultimately, I just want to find:

float totalDamage = DamagePerSecond * timeIntervalInSeconds;

This seems really frustratingly hard, and it's baffling that I haven't yet seen this covered after a good hour of looking through YouTube/Googling.

auto testX = std::chrono::milliseconds(5);
auto duration_s = std::chrono::duration_cast<std::chrono::seconds>(testX);
Log(L"%f\n" duration_s.count());  // This just prints out 0.00000, probably because type mismatch
Log(L"%i\n" duration_s.count());  // This just prints out 0, because there's not a whole number second yet

I tried to follow the solution here:

How to convert std::chrono::duration to double (seconds)?

auto testX = std::chrono::milliseconds(5);
float converted = std::chrono:duration<double>(testX).count();
Log(L"%f\n", converted);

But this yields the following errors:

error C2882: 'chrono': illegal use of namespace identifier in expression
error C2143: syntax error: missing ';' before ':'
error C2059: syntax error: ':'

CodePudding user response:

You may divide any two std::chrono::durations of any type or period to efficiently get a count in the common type.

template <class Rep, class Period>
constexpr double seconds(std::chrono::duration<Rep,Period> d)
{
    using namespace std::chrono_literals;

    // How many seconds?  Divide by one second!
    // The units cancel out and you get a number.
    return d / 1.0s;
}

Note that this technique can also give you a "count" of any unusual duration.

  • How many 2 minute intervals?

  • How many 33 nanosecond intervals?

Just divide by that amount.

CodePudding user response:

You were almost there, the syntax is this :

#include <chrono>
#include <iostream>

using namespace std::chrono_literals;

int main()
{
    auto duration = 125ms;

    // duration cast gives the number of counts in the unit you asked for.
    auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();

    // convert milliseconds to seconds by dividing by 1000
    auto seconds = static_cast<double>(milliseconds) / 1000.0;

    std::cout << seconds << "s";

    return 0;
}

Live demo : https://onlinegdb.com/r7G3QpZzT

CodePudding user response:

You could simply duration_cast to std::chrono::duration<double>:

template<class Duration>
constexpr double Damage(Duration d)
{
    using FloatSecond = std::chrono::duration<double>;

    constexpr double Dps = 1234.567;

    return Dps * std::chrono::duration_cast<FloatSecond>(d).count();
}

int main()
{
    using namespace std::chrono_literals;

    std::cout
        << Damage(1ms) << '\n'
        << Damage(5s) << '\n'
        << Damage(1min) << '\n';
}
  • Related