What is the correct way to format seconds in c++20 (using std::format) without also showing fractional digits?
This code:
#include <chrono>
#include <format>
#include <iostream>
int main()
{
std::cout << std::format("{:%H:%M:%S}", std::chrono::system_clock::now()) << std::endl;
std::cout << std::format("{:%H:%M:%OS}", std::chrono::system_clock::now()) << std::endl;
}
Produces this output (via trunk GCC (14.0.0 20230425)):
00:18:07.087240403
00:18:07.087622600
I just want the integer part (eg 00:18:07
without the trailing .087240403
).
It's very easy to remove the remainder from the resulting string after the fact (or manually extract the seconds and print them separately), but I'd be very surprised if that was the intended solution.
The formatting codes are described here. AFAICT there is no %S
variant that explicitly rounds or truncates the seconds to the nearest integer.
The explanation (from the link above) for %S (and %OS below) is:
Writes the second as a decimal number. If the number of seconds is less than 10, the result is prefixed with 0.
If the precision of the input cannot be exactly represented with seconds, then the format is a decimal floating-point number with a fixed format and a precision matching that of the precision of the input (or to a microseconds precision if the conversion to floating-point decimal seconds cannot be made within 18 fractional digits). The character for the decimal point is localized according to the locale.
The modified command %OS writes the locale's alternative representation.
GCC/glibc is functioning correctly here, right? (It seems to fit the explanation above).
If so, what's the intended way to achieve this?
(If this isn't trivially achievable, could this be considered potentially undesirable behavior, perhaps a STL defect?)
You can use time_point_cast
to convert its duration to seconds
and then format it:
auto now = std::chrono::time_point_cast<std::chrono::seconds>(
std::chrono::system_clock::now()
);
std::cout << std::format("{:%H:%M:%S}", now) << std::endl;