Title
Formatting of negative durations is not specified
Status
c++20
Section
[time.format]
Submitter
Tomasz Kamiński

Created on 2019-08-18.00:00:00 last changed 38 months ago

Messages

Date: 2020-02-13.18:06:22

Proposed resolution:

This wording is relative to N4830.

[Drafting note: With the above clarification, the specification of the operator<< for hh_mm_ss may be simplified to format("{:%T}", hms).]

  1. Modify [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 format_error is thrown.

    -?- The result of formatting a std::chrono::duration instance holding a negative value, or of an hh_mm_ss object h for which h.is_negative() is true, is equivalent to the output of the corresponding positive value, with a STATICALLY-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, […]

  2. Modify [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()));
    
Date: 2020-02-13.18:06:22

[ 2020-02; Status set to Immediate after LWG discussion Thursday in Prague. (Minor example wording cleanup) ]

Date: 2019-09-15.00:00:00

[ 2019-09-14; Howard improves wording ]

Date: 2019-09-14.00:00:00

[ 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<< for hh_mm_ss may be simplified to format("{:%T}", hms).]

  1. Modify [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 format_error is thrown.

    -?- The result of formatting a std::chrono::duration instance holding a negative value, or of an hh_mm_ss object h for which h.is_negative() is true, 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, […]

  2. Modify [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()));
    
Date: 2019-08-18.00:00:00

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.

History
Date User Action Args
2021-02-25 10:48:01adminsetstatus: wp -> c++20
2020-02-24 16:02:59adminsetstatus: immediate -> wp
2020-02-13 18:06:22adminsetmessages: + msg11073
2020-02-13 18:06:22adminsetstatus: new -> immediate
2019-09-14 15:46:00adminsetmessages: + msg10611
2019-09-14 12:35:21adminsetmessages: + msg10609
2019-08-22 19:14:34adminsetmessages: + msg10580
2019-08-18 00:00:00admincreate