On Wed, May 3, 2023, 5:43 AM Jonathan Wakely via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
> The currently required method may have the potential to be less efficient because it *requires* a conversion in user code, (and it's not easy for a user to determine whether this conversion is trivial). This is unlikely to be very important, however, as it's unlikely this function will be called often enough to noticeably affect performance.

Why would it be any more efficient for std::format to do chrono::duration_cast<seconds> (or chrono::floor) than for the user code to do it?

I don't really see a pressing need for this. If you don't want fractional seconds, don't use a representation that has subsecond resolution. One of the strengths of the std::chrono API is that you can choose your resolution and easily convert between them. I don't think std::format needs to provide that conversion as well.

I think it's unfortunate in retrospect that %S means what it means instead of just 2-digit integer seconds (for consistency with %H and %M, and also it's what %S does in strftime as well as other languages - like Rust, Python, and Ruby). But that ship has sailed.

That said, I do think a dedicated specifier for integral seconds and, correspondingly, the fractional part is worthwhile. For the same reason in general that adding stuff to the specifier is worthwhile: it composes better. If I have a wrapped time_point (whether optional<tp> or tuple<tp> or vector<tp>), it's easier to format the way you want it to if you can put the logic into the specifier rather than having to come up with a way to transform the value.

Additionally, the format string might come from a different source than the argument - which makes the suggested solution of having to do more work on the operand less viable. 

We could split into %s (integer part) and %f (fractional part), but we could also do what Rust and Ruby do and allow attaching a digit so you can specify how many digits the fractional part should have. So maybe %3f or %9f. And then likewise maybe %3S is always milliseconds and %0S is always seconds (and similarly %3T is %H:%M:%3S)? This means that we could easily specify the time point format we want without having to know the underlying representation - which is good because we don't actually even specify what system_clock::time_point's resolution is.