%I%p
should parse/format duration
since midnightSection: 30.12 [time.format], 30.13 [time.parse] Status: C++20 Submitter: Howard Hinnant Opened: 2019-09-02 Last modified: 2021-02-25
Priority: 0
View other active issues in [time.format].
View all other issues in [time.format].
View all issues with C++20 status.
Discussion:
It is clear how "%I%p"
parses and formats time points. What is not clear is how these
flags interact with durations. We should treat durations as "elapsed time since midnight". For example:
#include <chrono> #include <iostream> #include <string> #include <sstream> int main() { using namespace std; using namespace std::chrono; // Format { // format time_point with %I%p cout << format("{:%F %I%p}", sys_days{2019_y/August/10}+14h) << '\n'; } { // format duration with %I%p cout << format("{:%I%p}", 14h) << '\n'; } // Parse { // Parse %I%p as day-of-year combined with an hour into a time_point istringstream in{"2019-08-10 2pm"}; system_clock::time_point tp; in >> parse("%F %I%p", tp); cout << tp << '\n'; } { // Parse %I%p as number of hours into a duration istringstream in{"2pm"}; hours d; in >> parse("%I%p", d); cout << d << '\n'; } }
Output:
2019-08-10 02PM 02PM 2019-08-10 14:00:00.000000 14h
[2019-10 Status set to 'Tentatively Ready' after reflector discussion]
Proposed resolution:
This wording is relative to N4830.
Modify 30.12 [time.format] as indicated:
-3- Unless explicitly requested, the result of formatting a chrono type does not contain time zone abbreviation and time zone offset information. If the information is available, the conversion specifiers
-?- If the type being formatted does not contain the information that the format flag needs, an exception of type%Z
and%z
will format this information (respectively). [Note: If the information is not available and a%Z
or%z
conversion specifier appears in the chrono-format-spec, an exception of typeformat_error
is thrown, as described above. — end note]format_error
is thrown. [Example: Aduration
does not contain enough information to format as aweekday
— end example]. However if a flag refers to a "time of day" (e.g.%H
,%I
,%p
, etc.), then a specialization ofduration
is interpreted as the time of day elapsed since midnight.
Modify 30.13 [time.parse] as indicated:
[Drafting note: The modification of 30.13 [time.parse] p1 is intended to be non-conflictingly mergeable with the change suggested by LWG 3269 and LWG 3271 at the same paragraph.]
-1- Each parse overload specified in this subclause calls
[…] -10- Allfrom_stream
unqualified, so as to enable argument dependent lookup (6.5.4 [basic.lookup.argdep]). In the following paragraphs, letis
denote an object of typebasic_istream<charT, traits>
, wherecharT
andtraits
are template parameters in that context.from_stream
overloads behave as unformatted input functions, except that they have an unspecified effect on the value returned by subsequent calls tobasic_istream<>::gcount()
. Each overload takes a format string containing ordinary characters and flags which have special meaning. Each flag begins with a%
. Some flags can be modified byE
orO
. During parsing each flag interprets characters as parts of date and time types according to Table [tab:time.parse.spec]. Some flags can be modified by a width parameter given as a positive decimal integer called out asN
below which governs how many characters are parsed from the stream in interpreting the flag. All characters in the format string that are not represented in Table [tab:time.parse.spec], except for white space, are parsed unchanged from the stream. A white space character matches zero or more white space characters in the input stream. -?- If the type being parsed can not represent the information that the format flag refers to,is.setstate(ios_base::failbit)
is called. [Example: Aduration
cannot represent aweekday
— end example]. However if a flag refers to a "time of day" (e.g.%H
,%I
,%p
, etc.), then a specialization ofduration
is parsed as the time of day elapsed since midnight.