microsoft / microsoft/STL

`<chrono>` `<format>`: `duration` formatting ignores precision

Open
#4,200 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug chrono format
Dominant language
C++
Stars
11.1k
Forks
1.7k
Avg merge
4d 15h
Merged PRs (30d)
22

Description

When formatting a duration, we parse but appear to totally ignore precision:

C:\Temp>type meow.cpp
#include <chrono>
#include <format>
#include <iostream>
#include <string>
using namespace std;

int main() {
    cout << format("  double: {:.3}", 3.14159) << "\n";
    cout << format("duration: {:.3%Q}", 3.14159s) << "\n";
}
C:\Temp>cl /EHsc /nologo /W4 /std:c++latest /MTd /Od meow.cpp && meow
meow.cpp
  double: 3.14
duration: 3.14159

Curiously, libstdc++ and libc++ exhibit the same behavior: https://godbolt.org/z/15cYchz9q

Precision is allowed for floating-point durations by WG21-N4964 [time.format]/1:

Giving a precision specification in the chrono-format-spec is valid only for types that are specializations of std::chrono::duration for which the nested typedef-name rep denotes a floating-point type. For all other types, an exception of type format_error is thrown if the chrono-format-spec contains a precision specification.

Then [tab:time.format.spec] says:

Specifier Replacement
... ...
%Q The duration’s numeric value (as if extracted via .count()).
... ...
%S Seconds 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 produces the locale’s alternative representation.

I don't know what an explicitly specified precision is supposed to do for %S but ignoring it for %Q seems wrong. Why is it allowed in the chrono-format-spec if it's never used?

Am I right, or are three independent implementations right?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the meow.cpp reproducer and its duration formatting call, then read the cited [time.format] clauses for chrono-format-spec, %Q, and %S. Compare the observed output with the standard and determine the expected handling of explicit precision; done means the behavior is resolved against the specification and covered by an appropriate regression check.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.