C++ Logo


Advanced search

Re: [std-proposals] New draft proposal: Add "%s" (two-digit truncated-integer seconds) as a std::format conversion specifier for std::chrono time types.

From: Jonathan Wakely <cxx_at_[hidden]>
Date: Wed, 3 May 2023 17:14:55 +0100
On Wed, 3 May 2023, 16:21 Simon Hill, <protogrammer_at_[hidden]> wrote:

> > 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.
> I don't see a _pressing need_ either. It's just, IMHO, a very tiny QoL
> tweak.
> The standard doesn't specify whether or not the standard clocks actually
> have subsecond resolution (yes, you can obtain it in code, but that doesn't
> reduce verbosity). Also, you might want that precision elsewhere (I did).
> In the worst (albeit unlikely) case, if a clock currently has seconds
> resolution but is upgraded in the future, formatting could change. For
> example, file_clock.
> I do understand though that it's simple to just pass
> std::chrono::floor<std::chrono::seconds>(t) and be safe.
> But "std::chrono::floor<std::chrono::seconds>(t)" is still much more
> verbose than "(t)".
> > I don't find the consistency argument convincing either...
> I'm am in agreement with you ("that's probably good") that it would be bad
> to require floor<hours> & floor<minutes>. And I imagine that is the reason
> %H and %M are truncated. But I don't see that as an argument against
> _consistency_ per se.
> In a very similar example, the boolean operators && and || are boolean
> equivalents of the bitwise & and |, but there is no ^^ equivalent of ^. In
> that case, the reason is because && and || allow for short-circuiting,
> which can't apply to ^^.
> But people learn that a single logical operator is bitwise, and a double
> logical operator is boolean. They then have to remember that ^ doesn't have
> a bitwise equivalent.
> But there is no _harm_ in adding a ^^, even if the initial reason for &&
> and || doesn't apply. And there are other benefits, one of which is
> consistency. Consistency just means it's easier to learn, there's less to
> remember, and it's tidier. (Other benefits of ^^ are not requiring explicit
> casts like "bool(x) ^ bool(y)" (vs "x ^^ y"), and fewer bugs where coders
> accidentally bitwise compare instead of boolean.)
> My point here is, just because one reason only applies to part of the set
> (& and |, or %H and %M), doesn't mean it's actually a negative to do the
> rest of the set (^, %S) just so that people don't have to remember the
> inconsistency.
> For the other meaning of consistency: If almost every piece of software
> out there does "{:%H|%M|%S}"=>"HH|MM|SS" but C++ does not, it is going to
> confuse some programmers. I would bet the vast majority of people who use
> "%S" would expect it to be truncated just because that's how it is
> everywhere else.

Is it actually truncated elsewhere, or is the resolution just in seconds
anyway? C++ is unusual in supporting multiple precisions, where hours,
seconds and nanoseconds are all represented by the same class template. C++
doesn't have a "natural" precision for time. But that does mean you're
responsible for choosing an appropriate precision.

> > 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?
> My thinking was that, IIUC, there's an (unlikely) _potential_ inefficiency
> where an implementation of %s might not _require_ a cast (given that the
> underlying data of user-defined clocks is not specified), but it's pretty
> unlikely.

Unheard of, I think.

And not all time points and durations come from clocks anyway. Formatting
of chrono types isn't just for formatting values that come straight from

If your primary concern is formatting times from clocks, and you don't care
about formatting subsecond precision, I think you should just be converting
them to your preferred precision using time_point_cast or floor.

But anyway, the efficiency rationale was pretty weak, that's why it was
> last.
> And I do get that if you do ("{:%H:%M:%S}", t) and don't cast, it could
> also be less efficient due to repeated casts. However, that logic currently
> applies to %H:%M without %S.
> > and because %T would still use %S, it's arguably not any simpler.
> That's a good point. And "%t"s already used (why? isn't \t sufficient?
> (same for \n vs "%n"))

Because strftime supports them.

so you can't cleanly do %T/%S=fractional, %t/%s=truncated.
> =====================
> As this is my first proposal, I'm not clear on how minor an issue can be
> before it's not worth submitting.
> I mainly just wrote this because of Howard Hinnat's suggestion to do so,

I don't read Howard's SO comment as particularly supportive of the idea,
but maybe I'm wrong. Providing a link explaining how to submit a proposal
is not necessarily support for the proposal :-)

and to see what the process was like, although I do personally believe this
> is a beneficial proposal.
> How much of a cost is there to change the standard? Do issues that are as
> minor as this one is get discarded so as to not make extra work for the
> compiler devs?

The work to implement it is not the issue here. It makes the chrono
formatter code (slightly) larger and slower, for every call to std::format,
even for users who don't need the new feature. I'm not sure it's worth it,
when you can already do it using a cast. Your mileage may vary.

> Lastly, is there any hope for a proposal to add the ^^ operator?

Received on 2023-05-03 16:15:09