This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++20 status.

### 3317. Incorrect `operator<<` for floating-point durations

Section: 29.5.11 [time.duration.io] Status: C++20 Submitter: United States Opened: 2019-11-05 Last modified: 2021-02-25

Priority: 0

View all other issues in [time.duration.io].

View all issues with C++20 status.

Discussion:

Addresses US 334

`operator<<` for floating-point durations always produces output with six digits after the decimal point, and doesn't use the stream's locale either.

Proposed change:

Rewrite the specification to not rely on `to_string()` for floating-point formatting.

[2019-11 Status to Ready during Wednesday morning issue processing in Belfast.]

Proposed resolution:

This wording is relative to N4835.

1. Modify 29.5.11 [time.duration.io] as indicated:

   >     template<class charT, class traits, class Rep, class Period>
   >       basic_ostream<charT, traits>&
   >         operator<<(basic_ostream<charT, traits>& os, const duration<Rep, Period>& d);

   > > -1- Requires: `Rep` is an integral type whose integer conversion rank (6.8.6 [conv.rank]) is greater than or equal to that of `short`, or a floating-point type. `charT` is `char` or `wchar_t`.

   > > -2- Effects: Forms a `basic_string<charT, traits>` from `d.count()` using `to_string` if `charT` is `char`, or `to_wstring` if `charT` is `wchar_t`. Appends the units suffix described below to the `basic_string`. Inserts the resulting `basic_string` into `os`. [Note: This specification ensures that the result of this streaming operation will obey the width and alignment properties of the stream. — end note]Inserts the duration `d` onto the stream `os` as if it were implemented as follows:

   > > >     basic_ostringstream<charT, traits> s;
   > > >     s.flags(os.flags());
   > > >     s.imbue(os.getloc());
   > > >     s.precision(os.precision());
   > > >     s << d.count() << units_suffix;
   > > >     return os << s.str();

   > > -3- The units suffix `units_suffix` depends on the type `Period::type` as follows:

   > > 1. (3.1) — If `Period::type` is `atto`, the suffix `units_suffix` is `"as"`.

   > > 2. (3.2) — Otherwise, if `Period::type` is `femto`, the suffix `units_suffix` is `"fs"`.

   > > 3. (3.3) — Otherwise, if `Period::type` is `pico`, the suffix `units_suffix` is `"ps"`.

   > > 4. (3.4) — Otherwise, if `Period::type` is `nano`, the suffix `units_suffix` is `"ns"`.

   > > 5. (3.5) — Otherwise, if `Period::type` is `micro`, the suffix `units_suffix` is `"µs"` (`"\u00b5\u0073"`).

   > > 6. (3.6) — Otherwise, if `Period::type` is `milli`, the suffix `units_suffix` is `"ms"`.

   > > 7. (3.7) — Otherwise, if `Period::type` is `centi`, the suffix `units_suffix` is `"cs"`.

   > > 8. (3.8) — Otherwise, if `Period::type` is `deci`, the suffix `units_suffix` is `"ds"`.

   > > 9. (3.9) — Otherwise, if `Period::type` is `ratio<1>`, the suffix `units_suffix` is `"s"`.

   > > 10. (3.10) — Otherwise, if `Period::type` is `deca`, the suffix `units_suffix` is `"das"`.

   > > 11. (3.11) — Otherwise, if `Period::type` is `hecto`, the suffix `units_suffix` is `"hs"`.

   > > 12. (3.12) — Otherwise, if `Period::type` is `kilo`, the suffix `units_suffix` is `"ks"`.

   > > 13. (3.13) — Otherwise, if `Period::type` is `mega`, the suffix `units_suffix` is `"Ms"`.

   > > 14. (3.14) — Otherwise, if `Period::type` is `giga`, the suffix `units_suffix` is `"Gs"`.

   > > 15. (3.15) — Otherwise, if `Period::type` is `tera`, the suffix `units_suffix` is `"Ts"`.

   > > 16. (3.16) — Otherwise, if `Period::type` is `peta`, the suffix `units_suffix` is `"Ps"`.

   > > 17. (3.17) — Otherwise, if `Period::type` is `exa`, the suffix `units_suffix` is `"Es"`.

   > > 18. (3.18) — Otherwise, if `Period::type` is `ratio<60>`, the suffix `units_suffix` is `"min"`.

   > > 19. (3.19) — Otherwise, if `Period::type` is `ratio<3600>`, the suffix `units_suffix` is `"h"`.

   > > 20. (3.20) — Otherwise, if `Period::type` is `ratio<86400>`, the suffix `units_suffix` is `"d"`.

   > > 21. (3.21) — Otherwise, if `Period::type::den == 1`, the suffix `units_suffix` is `"[num]s"`.

   > > 22. (3.22) — Otherwise, the suffix `units_suffix` is `"[num/den]s"`.

   > > In the list above the use of `num` and `den` refer to the static data members of `Period::type`, which are converted to arrays of `charT` using a decimal conversion with no leading zeroes.

   > > -4- If `Period::type` is `micro`, but the character U+00B5 cannot be represented in the encoding used for `charT`, the unit suffix `units_suffix` `"us"` is used instead of `"µs"`.

   > > -5- Returns: `os`.