<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 3961: Does chrono::parse check format strings?</title>
<meta property="og:title" content="Issue 3961: Does chrono::parse check format strings?">
<meta property="og:description" content="C++ library issue. Status: New">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue3961.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#New">New</a> status.</em></p>
<h3 id="3961"><a href="lwg-active.html#3961">3961</a>. Does <code>chrono::parse</code> check format strings?</h3>
<p><b>Section:</b> 30.13 <a href="https://wg21.link/time.parse">[time.parse]</a> <b>Status:</b> <a href="lwg-active.html#New">New</a>
 <b>Submitter:</b> Jonathan Wakely <b>Opened:</b> 2023-07-28 <b>Last modified:</b> 2023-11-03</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="lwg-index-open.html#time.parse">active issues</a> in [time.parse].</p>
<p><b>View all other</b> <a href="lwg-index.html#time.parse">issues</a> in [time.parse].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#New">New</a> status.</p>
<p><b>Discussion:</b></p>
<p>
30.13 <a href="https://wg21.link/time.parse">[time.parse]</a> p16 says:
"If the type being parsed cannot represent the information that the format flag refers to, <code>is.setstate(ios_base::failbit)</code> is called."
Note it says "the format flag" singular. I had interpreted this as meaning that if the entire format string doesn't provide the info 
needed by the type, it fails. But that's not what it says.
It says that parsing fails if the type cannot represent
"the information that the format flag refers to". Which format flag?
Presumably this rule applies to each of them in turn.
So <code>"Monday 13:00" &gt;&gt; parse("%a %R", sec)</code> is required to fail,
rather than ignore the %a part and set <code>sec</code> to <code>13h</code>.
I don't think that is the intended design.
I think the phrasing of this rule is backwards. It shouldn't be focused on what info is provided by the format flag, 
but what info is needed by the type.
</p>

<p>
What should happen when <code>chrono::parse</code> is given a meaningless
format string like "%", or "%E", or "%Ea" or "%99a"?
Presumably that should set failbit, but I don't think we actually say so.
If the implementation should set failbit, is it conforming to do so before
extracting any characters?
</p>
<p>
Is it conforming to set failbit before extracting any characters if the
format string can never succeed for the parsable type?
Consider:
<pre><blockquote>std::chrono::seconds sec;
std::cin &gt;&gt; parse("%a", sec);
</blockquote></pre>

The type being parsed (<code>seconds</code>) cannot represent the information that
%a (a weekday) refers to, so we should set <code>cin.setstate(ios_base::failbit)</code>.
But should that happen before extracting any characters, or after extracting
a weekday string? If it's unspecified, should we say so explicitly?
</p>

<p>
Can a conforming implementation validate the format string before extracting
any characters, and fail early if parsing the actual istream contents can never
succeed? Or is <code>parse("%a", sec)</code> required to try to parse a valid
weekday name before setting <code>failbit</code>?
</p>


<p><i>[2023-11-02; Reflector poll]</i></p>

<p>
Set priority to 3 after reflector poll.
</p>



<p id="res-3961"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4950" title=" Working Draft, Standard for Programming Language C++">N4950</a>.
</p>

<ol>

<li><p>Modify 30.13 <a href="https://wg21.link/time.parse">[time.parse]</a> as indicated:</p>

<blockquote>
<p>
-15-
All <code>from_stream</code> overloads behave as unformatted input functions,
except that they have an unspecified effect on the value returned by subsequent 
calls to <code><del>basic_istream&lt;&gt;::</del><ins>is.</ins>gcount()</code>.
Each overload takes a format string containing ordinary characters and
flags which have special meaning.
Each flag begins with a <code>%</code>.
Some flags can be modified by <code>E</code> or <code>O</code>.
During parsing each flag interprets characters as parts of date and time types
according to Table 102.
Some flags can be modified by a width parameter given as
a positive decimal integer called out as <code><i>N</i></code> 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 102,
except for whitespace, are parsed unchanged from the stream.
A whitespace character matches zero or more whitespace characters
in the input stream.
</p>
<p>
<ins>
-?-
If a format string contains a <code>%</code> character that is not part of a flag
shown in Table 102, or a modifier that is not allowed for a flag,
<code>is.setstate(ios_base::failbit)</code> is called.
It is unspecified how many characters (if any) are extracted before the call
to <code>is.setstate(ios_base::failbit)</code>.
</ins>
</p>
<p>
-16-
If <ins>a value cannot be determined for</ins> the type being parsed
<ins>from the flags in the format string</ins>
<del>cannot represent the information that the format flag refers to</del>
<code>is.setstate(ios_base::failbit)</code> is called.
<ins>
It is unspecified how many characters (if any) are extracted before the call
to <code>is.setstate(ios_base::failbit)</code>.
</ins>
</p>
<p>
[<i>Example</i>:
A <code>duration</code> cannot represent a <del><code>weekday</code></del> <ins>weekday,
so <code>parse("%a", dur)</code> will always fail if the type of <code>dur</code>
is a specialization of <code>duration</code>.
Implementations can check the format string and set <code>failbit</code>
before extracting any characters.
</ins>
&mdash; <i>end example</i>]
</p>

</blockquote>
</li>
</ol>





</body>
</html>
