I've got the task to convert some C# code to C++ and I've problems with chrono. Goal is to round a time to a variable time span.
C#:
int iRoundTo = 30; // can be 45 or other variable value, not a const
DateTime dt = Floor(DateTime.Now, new TimeSpan(0, 0, 0, iRoundTo));
I found a solution with const iRoundTo but this is not what I'm looking for. How do I convert this to C++ with using std::chono?
C++:
std::chrono::seconds diff(iRoundTo);
auto dt = std::chrono::floor<diff>(Now);
This is not working due to compile error.
Thanks.
I'm doing a bit of guessing with this answer, but my guess is that you want to truncate the current time to the floor of the current half minute (in case of iRoundTo == 30
).
If I'm correct, this is easy to do as long as iRoundTo
is a compile-time constant.
#include <chrono>
#include <iostream>
int
main()
{
using RoundTo = std::chrono::duration<int, std::ratio<30>>;
auto Now = std::chrono::system_clock::now();
auto dt = std::chrono::floor<RoundTo>(Now);
std::cout << dt << '\n';
}
The above creates a new duration type that is 30 seconds long. It then gets the current time and floors it (truncates downwards) to the previous half minute unit. It then prints out the result. Everything before the print works in C++17. The printing (the last line) requires C++20.
Example output for me:
2022-01-18 01:45:30
The above code can also work pre-C++17 but in that case you'll need to find your own floor
(e.g. date.h) or use std::chrono::duration_cast
which truncates towards zero.
Update
In the comments below, it is explained that iRoundTo
is not a compile-time constant, but does always represent a multiple of seconds. In this case I would do this in two steps:
int iRoundTo = 30;
auto Now = std::chrono::system_clock::now();
// First truncate to seconds
auto dt = std::chrono::floor<std::chrono::seconds>(Now);
// Then subtract of the modulus according to iRoundTo
dt -= dt.time_since_epoch() % iRoundTo;
The sub-expression dt.time_since_epoch() % iRoundTo
has type seconds
and a value between 0s
and seconds{iRoundTo} - 1s
.