I have a user-provided duration
const int period_seconds = cfg.period_seconds;
I would like to floor
a time_point
to the granularity of that duration
.
I see that there is a std::chrono::floor
function for time_point
and duration
, but it's not immediately obvious how to use them to do what I'm looking for.
I have the following toy example which works:
const auto seconds = std::chrono::seconds{period_seconds};
const auto period = std::chrono::duration_cast<std::chrono::nanoseconds>(seconds);
const auto now = std::chrono::system_clock::now();
const auto floored = now - (now.time_since_epoch() % period);
The net effect of the above code, for a duration of 10 seconds would be the following:
now: 2022-04-19 15:06:26.781772408 floored: 2022-04-19 15:06:20.000000000 # so "floors" the 25.78 seconds to 20 seconds
I can't help but feel that working in terms of the time_since_epoch
and a modulus operator isn't the "right" way of getting the result I'm looking for...
Is there a "better" / recommended way to floor a time_point to some user-provided duration?
CodePudding user response:
Your solution looks pretty good to me. However it can be slightly simplified. There's no need to form the nanoseconds-precision period
. You can operate directly with seconds
:
const auto floored = now - (now.time_since_epoch() % seconds);
CodePudding user response:
You could use std::chrono::floor
with a custom duration, e.g. TenSecondsDuration
, like shown below (if you need to be able to create that custom duration at runtime, this won't be of much help though).
#include <chrono>
#include <fmt/core.h>
#include <iostream>
int main() {
using namespace std::chrono_literals;
using TenSecondsDuration = std::chrono::duration<int, std::ratio<10>>;
for (const auto& d : { 985s, 992s, 999s, 1006s, 1013s, 1020s }) {
fmt::print("{}s rounded to 10s = {}\n",
d.count(), std::chrono::floor<TenSecondsDuration>(d).count() * 10);
}
}
// Outputs:
//
// 985s rounded to 10s = 980
// 992s rounded to 10s = 990
// 999s rounded to 10s = 990
// 1006s rounded to 10s = 1000
// 1013s rounded to 10s = 1010
// 1020s rounded to 10s = 1020