Section: 30.12 [time.format] Status: C++20 Submitter: Tomasz Kamiński Opened: 2019-08-18 Last modified: 2021-02-25
Priority: 2
View other active issues in [time.format].
View all other issues in [time.format].
View all issues with C++20 status.
Discussion:
The current specification of the formatting for std::chrono::duration
and
std::hh_mm_ss
types is unclear in regards the the handling of negative values.
To illustrate:
std::cout << std::format("%H:%M:%S", -10'000s); // prints either -02:46:40 or -02:-46:-40
The indented behavior (and currently implemented, see here) is to apply the sign once, before the leftmost converted field.
[2019-09-14 Priority set to 2 based on reflector discussion]
Previous resolution [SUPERSEDED]:This wording is relative to N4830.
[Drafting note: With the above clarification, the specification of the
operator<<
forhh_mm_ss
may be simplified toformat("{:%T}", hms)
.]
Modify 30.12 [time.format] as indicated:
-2- Each conversion specifier conversion-spec is replaced by appropriate characters as described in Table [tab:time.format.spec]. Some of the conversion specifiers depend on the locale that is passed to the formatting function if the latter takes one, or the global locale otherwise. If the formatted object does not contain the information the conversion specifier refers to, an exception of type
-?- The result of formatting aformat_error
is thrown.std::chrono::duration
instance holding a negative value, or of anhh_mm_ss
objecth
for whichh.is_negative()
istrue
, is equivalent to the output of the corresponding positive value, with a-
character placed before the replacement of the leftmost conversion specifier. [Example:cout << format("%T", -10'000s); // prints: -02:46:40 cout << format("%H:%M:%S", -10'000s); // prints: -02:46:40 cout << format("minutes %M, hours %H, seconds %S", -10'000s); // prints: minutes -46, hours 02, seconds 40— end example]
-3- Unless explicitly requested, […]Modify 30.9.3 [time.hms.nonmembers] as indicated:
template<class charT, class traits, class Duration> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const hh_mm_ss<Duration>& hms);-1- Effects: Equivalent to:
return os << format(os.getloc(),hms.is_negative() ? STATICALLY-WIDEN<charT>("-{:%T}") :STATICALLY-WIDEN<charT>("{:%T}"),abs(hms.to_duration()));
[2019-09-14; Howard improves wording]
[2020-02; Status set to Immediate after LWG discussion Thursday in Prague. (Minor example wording cleanup)]
Proposed resolution:
This wording is relative to N4830.
[Drafting note: With the above clarification, the specification of the
operator<<
forhh_mm_ss
may be simplified toformat("{:%T}", hms)
.]
Modify 30.12 [time.format] as indicated:
-2- Each conversion specifier conversion-spec is replaced by appropriate characters as described in Table [tab:time.format.spec]. Some of the conversion specifiers depend on the locale that is passed to the formatting function if the latter takes one, or the global locale otherwise. If the formatted object does not contain the information the conversion specifier refers to, an exception of type
-?- The result of formatting aformat_error
is thrown.std::chrono::duration
instance holding a negative value, or of anhh_mm_ss
objecth
for whichh.is_negative()
istrue
, is equivalent to the output of the corresponding positive value, with aSTATICALLY-WIDEN<charT>("-")
character sequence placed before the replacement of the leftmost conversion specifier. [Example:cout << format("{%:T}", -10'000s); // prints: -02:46:40 cout << format("{:%H:%M:%S}", -10'000s); // prints: -02:46:40 cout << format("{:minutes %M, hours %H, seconds %S}", -10'000s); // prints: minutes -46, hours 02, seconds 40— end example]
-3- Unless explicitly requested, […]
Modify 30.9.3 [time.hms.nonmembers] as indicated:
template<class charT, class traits, class Duration> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const hh_mm_ss<Duration>& hms);-1- Effects: Equivalent to:
return os << format(os.getloc(),hms.is_negative() ? STATICALLY-WIDEN<charT>("-{:%T}") :STATICALLY-WIDEN<charT>("{:%T}"),abs(hms.to_duration()));