Rewrite of the to_stream/format/from_stream/parse docs:

* The bulk of the description is moved from tz.html to date.html.

* The format and parse flags are now described in detail, instead of
  implicitly relying on the C and POSIX specs.  This gives me room
  to specify a few corner cases that are either under-specified in
  the official specs, or to add extensions.

* The from_stream / to_stream specifications are now located with
  each specific type that implements them.  This allows more detailed
  documentation as to how each type interacts with the from_stream /
  to_stream system.

* The format and parse functions are now more clearly separated from
  to_stream and from_stream, and are documented to be nothing more
  than syntax sugar on top of any type that choses to implement
  to_stream or from_stream.
This commit is contained in:
Howard Hinnant
2017-04-01 22:25:28 -04:00
parent 82c6d6a3a4
commit c10b729273
2 changed files with 1438 additions and 481 deletions

1300
date.html

File diff suppressed because it is too large Load Diff

619
tz.html
View File

@@ -26,7 +26,7 @@
<br/> <br/>
<br/> <br/>
<a href="mailto:howard.hinnant@gmail.com">Howard E. Hinnant</a><br/> <a href="mailto:howard.hinnant@gmail.com">Howard E. Hinnant</a><br/>
2017-03-25<br/> 2017-04-01<br/>
</address> </address>
<hr/> <hr/>
<h1 align=center>Time Zone Database Parser</h1> <h1 align=center>Time Zone Database Parser</h1>
@@ -57,10 +57,6 @@
<li><a href="#time_zone"><code>time_zone</code></a></li> <li><a href="#time_zone"><code>time_zone</code></a></li>
<li><a href="#zoned_time"><code>zoned_time</code></a></li> <li><a href="#zoned_time"><code>zoned_time</code></a></li>
<li><a href="#make_zoned"><code>make_zoned</code></a></li> <li><a href="#make_zoned"><code>make_zoned</code></a></li>
<li><a href="#to_stream"><code>to_stream</code></a></li>
<li><a href="#format"><code>format</code></a></li>
<li><a href="#from_stream"><code>from_stream</code></a></li>
<li><a href="#parse"><code>parse</code></a></li>
<li><a href="#utc_clock"><code>utc_clock</code></a></li> <li><a href="#utc_clock"><code>utc_clock</code></a></li>
<li><a href="#tai_clock"><code>tai_clock</code></a></li> <li><a href="#tai_clock"><code>tai_clock</code></a></li>
<li><a href="#gps_clock"><code>gps_clock</code></a></li> <li><a href="#gps_clock"><code>gps_clock</code></a></li>
@@ -529,7 +525,7 @@ zone, and no <code>clock::now()</code>. It is the <code>void*</code> of
</p></li> </p></li>
<li><p> <li><p>
<code>time_zone</code>: This represents a specific geographical area, and all <code>time_zone</code>: This represents a specific geographical area, and all
time zone related information for this area over all time. This includes a time zone related information for this area over all time. This includes a
name for the area, and for any specific point in time, the UTC offset, the name for the area, and for any specific point in time, the UTC offset, the
abbreviation, and additional information. abbreviation, and additional information.
@@ -1513,7 +1509,7 @@ useful for debugging this library.
<code>time_point</code> with precision <code>Duration</code>. If <code>seconds</code> <code>time_point</code> with precision <code>Duration</code>. If <code>seconds</code>
is not implicitly convertible to <code>Duration</code>, the instantiation is ill-formed. is not implicitly convertible to <code>Duration</code>, the instantiation is ill-formed.
[<i>Note:</i> There exist <code>time_zone</code>s with UTC offsets that require a [<i>Note:</i> There exist <code>time_zone</code>s with UTC offsets that require a
precision of <code>seconds</code>. <i>&mdash; end note:</i>] precision of <code>seconds</code>. <i>&mdash; end note:</i>]
</p> </p>
<pre> <pre>
@@ -1573,6 +1569,15 @@ operator==(const zoned_time&lt;Duration1&gt;&amp; x, const zoned_time&lt;Duratio
template &lt;class Duration1, class Duration2&gt; template &lt;class Duration1, class Duration2&gt;
bool bool
operator!=(const zoned_time&lt;Duration1&gt;&amp; x, const zoned_time&lt;Duration2&gt;&amp; y); operator!=(const zoned_time&lt;Duration1&gt;&amp; x, const zoned_time&lt;Duration2&gt;&amp; y);
template &lt;class CharT, class Traits, class Duration&gt;
std::basic_ostream&lt;class CharT, class Traits&gt;&amp;
operator&lt;&lt;(std::basic_ostream&lt;class CharT, class Traits&gt;&amp; os, const zoned_time&lt;Duration&gt;& t)
template &lt;class CharT, class Traits, class Duration&gt;
void
to_stream(std::basic_ostream&lt;CharT, Traits&gt;&amp; os, const CharT* fmt,
const zoned_time&lt;Duration&gt;&amp; tp);
</pre> </pre>
<p> <p>
@@ -1879,14 +1884,28 @@ operator&lt;&lt;(std::basic_ostream&lt;class CharT, class Traits&gt;&amp; os, co
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
<i>Effects:</i> Streams <code>t</code> to <code>os</code> using the format "%F %T %Z" <i>Effects:</i> Calls <code>to_stream(os, "%F %T %Z", t)</code>.
and the value returned from <code>t.get_local_time()</code>.
</p> </p>
<p> <p>
<i>Returns:</i> <code>os</code>. <i>Returns:</i> <code>os</code>.
</p> </p>
</blockquote> </blockquote>
<pre>
template &lt;class CharT, class Traits, class Duration&gt;
void
to_stream(std::basic_ostream&lt;CharT, Traits&gt;&amp; os, const CharT* fmt,
const zoned_time&lt;Duration&gt;&amp; tp);
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs a copy of the <code>sys_info</code> object by calling
<code>tp.get_info()</code> (stored in a local named <code>info</code> for example).
Then calls <code>to_stream(os, fmt, tp.get_local_time(), &amp;info.abbrev, &amp;info.offset)</code>.
</p>
</blockquote>
</blockquote> </blockquote>
<a name="make_zoned"></a><h3><code>make_zoned</code></h3> <a name="make_zoned"></a><h3><code>make_zoned</code></h3>
@@ -2024,438 +2043,6 @@ make_zoned(const std::string&amp; name, const sys_time&lt;Duration&gt;&amp; st)
</blockquote> </blockquote>
<a name="to_stream"></a><h3><code>to_stream</code></h3>
<blockquote>
<pre>
template &lt;class CharT, class Traits&gt;
void
to_stream(std::basic_ostream&lt;CharT, Traits&gt;&amp; os, const CharT* fmt,
const year&amp; y);
</pre>
<pre>
template &lt;class CharT, class Traits&gt;
void
to_stream(std::basic_ostream&lt;CharT, Traits&gt;&amp; os, const CharT* fmt,
const month&amp; m);
</pre>
<pre>
template &lt;class CharT, class Traits&gt;
void
to_stream(std::basic_ostream&lt;CharT, Traits&gt;&amp; os, const CharT* fmt,
const day&amp; d);
</pre>
<pre>
template &lt;class CharT, class Traits&gt;
void
to_stream(std::basic_ostream&lt;CharT, Traits&gt;&amp; os, const CharT* fmt,
const weekday&amp; wd);
</pre>
<pre>
template &lt;class CharT, class Traits&gt;
void
to_stream(std::basic_ostream&lt;CharT, Traits&gt;&amp; os, const CharT* fmt,
const year_month&amp; ym);
</pre>
<pre>
template &lt;class CharT, class Traits&gt;
void
to_stream(std::basic_ostream&lt;CharT, Traits&gt;&amp; os, const CharT* fmt,
const month_day&amp; md);
</pre>
<pre>
template &lt;class CharT, class Traits, , class Rep, class Period&gt;
void
to_stream(std::basic_ostream&lt;CharT, Traits&gt;&amp; os, const CharT* fmt,
const std::chrono::duration&lt;Rep, Period&gt;&amp; d);
</pre>
<pre>
template &lt;class CharT, class Traits, , class Rep, class Period&gt;
void
to_stream(std::basic_ostream&lt;CharT, Traits&gt;&amp; os, const CharT* fmt,
const year_month_day&amp; ymd);
</pre>
<pre>
template &lt;class CharT, class Traits, class Duration&gt;
void
to_stream(std::basic_ostream&lt;CharT, Traits&gt;&amp; os, const CharT* fmt,
const local_time&lt;Duration&gt;&amp; tp);
</pre>
<pre>
template &lt;class CharT, class Traits, class Duration&gt;
void
to_stream(std::basic_ostream&lt;CharT, Traits&gt;&amp; os, const CharT* fmt,
const sys_time&lt;Duration&gt;&amp; tp);
</pre>
<pre>
template &lt;class CharT, class Traits, class Duration&gt;
void
to_stream(std::basic_ostream&lt;CharT, Traits&gt;&amp; os, const CharT* fmt,
const zoned_time&lt;Duration&gt;&amp; tp);
</pre>
<pre>
template &lt;class CharT, class Traits, class Duration&gt;
void
to_stream(std::basic_ostream&lt;CharT, Traits&gt;&amp; os, const CharT* fmt,
const utc_time&lt;Duration&gt;&amp; tp);
</pre>
<pre>
template &lt;class CharT, class Traits, class Duration&gt;
void
to_stream(std::basic_ostream&lt;CharT, Traits&gt;&amp; os, const CharT* fmt,
const tai_time&lt;Duration&gt;&amp; tp);
</pre>
<pre>
template &lt;class CharT, class Traits, class Duration&gt;
void
to_stream(std::basic_ostream&lt;CharT, Traits&gt;&amp; os, const CharT* fmt,
const gps_time&lt;Duration&gt;&amp; tp);
</pre>
<blockquote>
<p>
These are lower-level functions with respect to <code>format</code>. These functions
will <i>format</i> directly to a <i>stream</i>. If you use these you will not be able
to align your formatted time stamp within a <code>width</code> respecting the stream's
<code>adjustfield</code>. But in forgoing that utility you may realize some performance
gains over <code>format</code> as nothing in the implementation of <code>to_stream</code>
creates temporary strings or streams to format into.
</p>
</blockquote>
</blockquote>
<a name="format"></a><h3><code>format</code></h3>
<blockquote>
<pre>
template &lt;class CharT, class Streamable&gt;
std::basic_string&lt;CharT&gt;
format(const std::locale&amp; loc, const CharT* fmt, const Streamable&amp; tp);
template &lt;class CharT, class Streamable&gt;
std::basic_string&lt;CharT&gt;
format(const CharT* fmt, const Streamable&amp; tp);
template &lt;class CharT, class Traits, class Streamable&gt;
std::basic_string&lt;CharT&gt;
format(const std::locale&amp; loc, const std::basic_string&lt;CharT, Traits&gt;&amp; fmt, const Streamable&amp; tp);
template &lt;class CharT, class Traits, class Streamable&gt;
std::basic_string&lt;CharT&gt;
format(const std::basic_string&lt;CharT, Traits&gt;&amp; fmt, const Streamable&amp; tp);
</pre>
<blockquote>
<p>
<i>Remarks:</i> These functions do not participate in overload resolution unless
<code>Streamable</code> has a <code>to_stream</code> overload of the form described in the
previous section.
</p>
<p>
<i>Effects:</i> These functions create a formatted time stamp using the
arguments, returning the result in a <code>std::string</code>.
</p>
<blockquote>
<p>
If a <code>locale</code> is passed in, then that <code>locale</code> is used for
any formatting that requires a <code>locale</code>. If no <code>locale</code>
is passed in, then if a <code>locale</code> is required for formatting, a
default constructed <code>locale</code> will be used (which makes a copy of the
global <code>locale</code>).
</p>
<p>
The <code>format</code> string follows the rules as specified for
<code>std::time_put</code> with the following exceptions:
</p>
<ul>
<li><p>
If <code>%S</code> or <code>%T</code> appears in the <code>format</code> string
and the argument <code>tp</code> has precision that can not be exactly represented
with seconds, then seconds
are formatted as a decimal floating point number with a fixed format and a
precision matching that of the precision of <code>tp</code> (or to a microseconds precision
if the conversion to floating point decimal seconds can not be made within 18 digits).
The character for the decimal point is localized according to the <code>locale</code>.
</p></li>
<li><p>
If <code>%z</code> appears in the format, the behavior depends on the type of
<code>tp</code>:
</p>
<ul>
<li>
<code>local_time</code>: An exception of type <code>std::runtime_error</code> is thrown.
</li>
<li>
<code>zoned_time</code>: The offset associated with <code>tp.get_time_zone()</code> is
used.
</li>
<li>
<code>sys_time</code>: <code>"+0000"</code> is used.
</li>
</ul>
<p>
If <code>%z</code> is modified by either <code>E</code> or <code>O</code>
(that is, <code>%Ez</code> or <code>%Oz</code>), then a colon is inserted
between the hours and minutes: <code>+00:00</code>.
</p>
</li>
<li><p>
If <code>%Z</code> appears in the format, the behavior depends on the type of
<code>tp</code>:
</p>
<ul>
<li>
<code>local_time</code>: An exception of type <code>std::runtime_error</code> is thrown.
</li>
<li>
<code>zoned_time</code>: The abbreviation associated with
<code>tp.get_time_zone()</code> is used.
</li>
<li>
<code>sys_time</code>: <code>"UTC"</code> is used.
</li>
</ul>
</li>
</ul>
<p>
For the overloads taking a <code>zoned_time</code> it is the value returned by
<code>tz.get_local_time()</code> that is formatted.
</p>
</blockquote>
<p>
<i>Returns:</i> The formatted string.
</p>
</blockquote>
</blockquote>
<a name="from_stream"></a><h3><code>from_stream</code></h3>
<blockquote>
<pre>
template &lt;class CharT, class Traits, class Alloc = std::allocator&lt;CharT&gt;&gt;
void
from_stream(std::basic_istream&lt;CharT, Traits&gt;&amp; is, const CharT* fmt, year&amp; y,
std::basic_string&lt;CharT, Traits, Alloc&gt;* abbrev = nullptr,
std::chrono::minutes* offset = nullptr);
template &lt;class CharT, class Traits, class Alloc = std::allocator&lt;CharT&gt;&gt;
void
from_stream(std::basic_istream&lt;CharT, Traits&gt;&amp; is, const CharT* fmt, month&amp; m,
std::basic_string&lt;CharT, Traits, Alloc&gt;* abbrev = nullptr,
std::chrono::minutes* offset = nullptr);
template &lt;class CharT, class Traits, class Alloc = std::allocator&lt;CharT&gt;&gt;
void
from_stream(std::basic_istream&lt;CharT, Traits&gt;&amp; is, const CharT* fmt, day&amp; d,
std::basic_string&lt;CharT, Traits, Alloc&gt;* abbrev = nullptr,
std::chrono::minutes* offset = nullptr);
template &lt;class CharT, class Traits, class Alloc = std::allocator&lt;CharT&gt;&gt;
void
from_stream(std::basic_istream&lt;CharT, Traits&gt;&amp; is, const CharT* fmt, weekday&amp; wd,
std::basic_string&lt;CharT, Traits, Alloc&gt;* abbrev = nullptr,
std::chrono::minutes* offset = nullptr);
template &lt;class CharT, class Traits, class Alloc = std::allocator&lt;CharT&gt;&gt;
void
from_stream(std::basic_istream&lt;CharT, Traits&gt;&amp; is, const CharT* fmt, year_month&amp; ym,
std::basic_string&lt;CharT, Traits, Alloc&gt;* abbrev = nullptr,
std::chrono::minutes* offset = nullptr);
template &lt;class CharT, class Traits, class Alloc = std::allocator&lt;CharT&gt;&gt;
void
from_stream(std::basic_istream&lt;CharT, Traits&gt;&amp; is, const CharT* fmt, month_day&amp; md,
std::basic_string&lt;CharT, Traits, Alloc&gt;* abbrev = nullptr,
std::chrono::minutes* offset = nullptr);
template &lt;class CharT, class Traits&gt;
void
from_stream(std::basic_istream&lt;CharT, Traits&gt;&amp; is, const CharT* fmt,
year_month_day&amp; ymd, std::basic_string&lt;CharT, Traits&gt;* abbrev = nullptr,
std::chrono::minutes* offset = nullptr);
template &lt;class Duration, class CharT, class Traits&gt;
void
from_stream(std::basic_istream&lt;CharT, Traits&gt;&amp; is, const CharT* fmt,
sys_time&lt;Duration&gt;&amp; tp, std::basic_string&lt;CharT, Traits&gt;* abbrev = nullptr,
std::chrono::minutes* offset = nullptr);
template &lt;class Duration, class CharT, class Traits&gt;
void
from_stream(std::basic_istream&lt;CharT, Traits&gt;&amp; is, const CharT* fmt,
local_time&lt;Duration&gt;&amp; tp, std::basic_string&lt;CharT, Traits&gt;* abbrev = nullptr,
std::chrono::minutes* offset = nullptr);
template &lt;class Rep, class Period, class CharT, class Traits&gt;
void
from_stream(std::basic_istream&lt;CharT, Traits&gt;&amp; is, const CharT* fmt,
std::chrono::duration&lt;Rep, Period&gt;&amp; d,
std::basic_string&lt;CharT, Traits&gt;* abbrev = nullptr,
std::chrono::minutes* offset = nullptr);
template &lt;class Duration, class CharT, class Traits&gt;
void
from_stream(std::basic_istream&lt;CharT, Traits&gt;&amp; is, const CharT* fmt,
utc_time&lt;Duration&gt;&amp; tp, std::basic_string&lt;CharT, Traits&gt;* abbrev = nullptr,
std::chrono::minutes* offset = nullptr);
template &lt;class Duration, class CharT, class Traits&gt;
void
from_stream(std::basic_istream&lt;CharT, Traits&gt;&amp; is, const CharT* fmt,
tai_time&lt;Duration&gt;&amp; tp, std::basic_string&lt;CharT, Traits&gt;* abbrev = nullptr,
std::chrono::minutes* offset = nullptr);
template &lt;class Duration, class CharT, class Traits&gt;
void
from_stream(std::basic_istream&lt;CharT, Traits&gt;&amp; is, const CharT* fmt,
gps_time&lt;Duration&gt;&amp; tp, std::basic_string&lt;CharT, Traits&gt;* abbrev = nullptr,
std::chrono::minutes* offset = nullptr);
</pre>
<blockquote>
<p>
<i>Effects:</i> These functions attempt to parse an object out of
<code>is</code> according to <code>fmt</code>. If the parse is unsuccessful,
calls <code>is.setstate(std::ios::failbit)</code> which may throw an exception.
<code>tp</code>, <code>*abbrev</code>, and <code>*offset</code> are altered only in
the event of a successful parse, for the latter two, only if they are not equal to
<code>nullptr</code>.
</p>
<blockquote>
<p>
The <code>format</code> string follows the rules as specified for <code>std::time_get</code>
with the following exceptions:
</p>
<ul>
<li><p>
If <code>%F</code> appears in the <code>format</code> string it is interpreted as
<code>%Y-%m-%d</code>.
</p></li>
<li><p>
If <code>%S</code> or <code>%T</code> appears in the <code>format</code> string and the
argument <code>tp</code> has precision that is not implicitly convertible to seconds, then
the seconds are parsed as a <code>double</code>, and if that parse is successful
contributes to the time stamp as if
<code>round&lt;Duration&gt;(duration&lt;double&gt;{s})</code> where <code>s</code> is a
local variable holding the parsed <code>double</code>.
</p></li>
<li><p>
If <code>%z</code> appears in the <code>format</code> string and an offset is
successfully parsed, the overloads taking <code>sys_time</code>, <code>utc_time</code>,
<code>tai_time</code> and <code>gps_time</code> interpret the
parsed time as a local time and subtracts the offset prior to assigning the
value to <code>tp</code>, resulting in a value of <code>tp</code> representing a
UTC timestamp. The remaining overloads require a valid
parse of the offset, but then ignore the offset in assigning a value to
<code>tp</code>. If <code>offset</code> is not equal to <code>nullptr</code>,
on successful parse <code>*offset</code> will hold the value represented by
<code>%z</code> if present, or will be assigned <code>0min</code> if
<code>%z</code> is not present.
</p>
<p>
The format of the offset is <code>+/-hhmm</code>. The leading plus or minus
sign is required. If the format string was modified (i.e. <code>%Ez</code>
or <code>%Oz</code>), a colon is required between hours and minutes, and the leading
hours digit is optional:
<code>+/-[h]h:mm</code>.
</p>
</li>
<li><p>
If <code>%Z</code> appears in the <code>format</code> string then an
abbreviation is required in that position for a successful parse. The
abbreviation will be parsed as a <code>std::basic_string&lt;CharT, Traits&gt;</code>
(delimited by white
space). The parsed abbreviation does not have to be a valid time zone
abbreviation, and has no impact on the value parsed into <code>tp</code>. If
<code>abbrev</code> is not equal to <code>nullptr</code> one can discover what
that parsed abbreviation is. On successful parse, and if <code>abbrev != nullptr</code>,
<code>*abbrev</code> will be
assigned the value represented by <code>%Z</code> if present, or assigned the
empty string if <code>%Z</code> is not present.
</p></li>
</ul>
</blockquote>
<p>
<i>Note:</i> There is no unique mapping from a time zone abbreviation to a
<code>time_zone</code>. But given a time zone abbreviation and a <code>sys_time</code>
or <code>local_time</code>, one could make a list of potential <code>time_zone</code>s.
Given a UTC offset, one might even narrow that list down further.
</p>
</blockquote>
</blockquote>
<a name="parse"></a><h3><code>parse</code></h3>
<blockquote>
<p>
Each of the functions below return a <i>manipulator</i> which can be used to extract the
desired information from a stream. These functions do not participate in overload
resolution unless <code>Parsable</code> has a corresponding <code>from_stream</code>
overload.
</p>
<pre>
template &lt;class Parsable, class CharT, class Traits&gt;
<i>unspecified</i>
parse(const std::basic_string&lt;CharT, Traits&gt;&amp; format, Parsable&amp; tp);
template &lt;class Parsable, class CharT, class Traits&gt;
<i>unspecified</i>
parse(const std::basic_string&lt;CharT, Traits&gt;&amp; format, Parsable&amp; tp,
std::basic_string&lt;CharT, Traits&gt;&amp; abbrev);
template &lt;class Parsable, class CharT, class Traits&gt;
<i>unspecified</i>
parse(const std::basic_string&lt;CharT, Traits&gt;&amp; format, Parsable&amp; tp,
std::chrono::minutes&amp; offset);
template &lt;class Parsable, class CharT, class Traits&gt;
<i>unspecified</i>
parse(const std::basic_string&lt;CharT, Traits&gt;&amp; format, Parsable&amp; tp,
std::basic_string&lt;CharT, Traits&gt;&amp; abbrev, std::chrono::minutes&amp; offset);
// const CharT* formats
template &lt;class Parsable, class CharT&gt;
<i>unspecified</i>
parse(const CharT* format, Parsable&amp; tp);
template &lt;class Parsable, class CharT, class Traits&gt;
<i>unspecified</i>
parse(const CharT* format, Parsable&amp; tp, std::basic_string&lt;CharT, Traits&gt;&amp; abbrev);
template &lt;class Parsable, class CharT&gt;
<i>unspecified</i>
parse(const CharT* format, Parsable&amp; tp, std::chrono::minutes&amp; offset);
template &lt;class Parsable, class CharT, class Traits&gt;
<i>unspecified</i>
parse(const CharT* format, Parsable&amp; tp,
std::basic_string&lt;CharT, Traits&gt;&amp; abbrev, std::chrono::minutes&amp; offset);
</pre>
</blockquote>
<a name="utc_clock"></a><h3><code>utc_clock</code></h3> <a name="utc_clock"></a><h3><code>utc_clock</code></h3>
<blockquote> <blockquote>
<pre> <pre>
@@ -2561,15 +2148,53 @@ operator&lt;&lt;(std::basic_ostream&lt;class CharT, class Traits&gt;&amp; os, co
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
<i>Effects:</i> Streams <code>t</code> to <code>os</code> using the format "%F %T". This <i>Effects:</i> Calls <code>to_stream(os, "%F %T", t)</code>.
differs from streaming <code>sys_time</code> only by the use of <code>60</code> for the
seconds specifier when the value represents an inserted leap second.
</p> </p>
<p> <p>
<i>Returns:</i> <code>os</code>. <i>Returns:</i> <code>os</code>.
</p> </p>
</blockquote> </blockquote>
<pre>
template &lt;class CharT, class Traits, class Duration&gt;
void
to_stream(std::basic_ostream&lt;CharT, Traits&gt;&amp; os, const CharT* fmt,
const utc_time&lt;Duration&gt;&amp; tp);
</pre>
<blockquote>
<p>
<i>Effects:</i> Inserts <code>tp</code> into <code>os</code> using the format
string <code>fmt</code> as specified by the
<a href="date.html#to_stream_formatting"><code>to_stream</code> formatting flags</a>.
Time points representing leap second insertions which format seconds will show
<code>60</code> in the seconds field.
If <code>%Z</code> is in the formatting string <code>"UTC"</code> will be used.
If <code>%z</code> is in the formatting string <code>"+0000"</code> will be used.
</p>
</blockquote>
<pre>
template &lt;class Duration, class CharT, class Traits&gt;
void
from_stream(std::basic_istream&lt;CharT, Traits&gt;&amp; is, const CharT* fmt,
utc_time&lt;Duration&gt;&amp; tp, std::basic_string&lt;CharT, Traits&gt;* abbrev = nullptr,
std::chrono::minutes* offset = nullptr);
</pre>
<blockquote>
<p>
<i>Effects:</i> Extracts <code>tp</code> from <code>is</code> using the format string
<code>fmt</code> as specified by the
<a href="date.html#from_stream_formatting"><code>from_stream</code> formatting flags</a>.
If <code>%z</code> is present, the parsed offset will be subtracted from the parsed time.
If <code>abbrev</code> is not equal to <code>nullptr</code>, the information parsed by
<code>%Z</code> (if present) will be placed in <code>*abbrev</code>. If
<code>offset</code> is not equal to <code>nullptr</code>, the information parsed by
<code>%z</code> (if present) will be placed in <code>*offset</code>.
</p>
</blockquote>
</blockquote> </blockquote>
<a name="tai_clock"></a><h3><code>tai_clock</code></h3> <a name="tai_clock"></a><h3><code>tai_clock</code></h3>
@@ -2667,20 +2292,51 @@ operator&lt;&lt;(std::basic_ostream&lt;class CharT, class Traits&gt;&amp; os, co
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
<i>Effects:</i> Creates a <code>sys_time</code> from <code>t</code> as if by: <i>Effects:</i> Calls <code>to_stream(os, "%F %T", t)</code>.
</p>
<blockquote><pre>
auto tp = sys_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;{t.time_since_epoch()} -
(sys_days{1970_y/jan/1} - sys_days{1958_y/jan/1});
</pre></blockquote>
<p>
And then streams that <code>sys_time</code>: <code>os &lt;&lt; tp</code>.
</p> </p>
<p> <p>
<i>Returns:</i> <code>os</code>. <i>Returns:</i> <code>os</code>.
</p> </p>
</blockquote> </blockquote>
<pre>
template &lt;class CharT, class Traits, class Duration&gt;
void
to_stream(std::basic_ostream&lt;CharT, Traits&gt;&amp; os, const CharT* fmt,
const tai_time&lt;Duration&gt;&amp; tp);
</pre>
<blockquote>
<p>
<i>Effects:</i> Inserts <code>tp</code> into <code>os</code> using the format
string <code>fmt</code> as specified by the
<a href="date.html#to_stream_formatting"><code>to_stream</code> formatting flags</a>.
If <code>%Z</code> is in the formatting string <code>"TAI"</code> will be used.
If <code>%z</code> is in the formatting string <code>"+0000"</code> will be used.
</p>
</blockquote>
<pre>
template &lt;class Duration, class CharT, class Traits&gt;
void
from_stream(std::basic_istream&lt;CharT, Traits&gt;&amp; is, const CharT* fmt,
tai_time&lt;Duration&gt;&amp; tp, std::basic_string&lt;CharT, Traits&gt;* abbrev = nullptr,
std::chrono::minutes* offset = nullptr);
</pre>
<blockquote>
<p>
<i>Effects:</i> Extracts <code>tp</code> from <code>is</code> using the format string
<code>fmt</code> as specified by the
<a href="date.html#from_stream_formatting"><code>from_stream</code> formatting flags</a>.
If <code>%z</code> is present, the parsed offset will be subtracted from the parsed time.
If <code>abbrev</code> is not equal to <code>nullptr</code>, the information parsed by
<code>%Z</code> (if present) will be placed in <code>*abbrev</code>. If
<code>offset</code> is not equal to <code>nullptr</code>, the information parsed by
<code>%z</code> (if present) will be placed in <code>*offset</code>.
</p>
</blockquote>
</blockquote> </blockquote>
<a name="gps_clock"></a><h3><code>gps_clock</code></h3> <a name="gps_clock"></a><h3><code>gps_clock</code></h3>
@@ -2777,20 +2433,51 @@ operator&lt;&lt;(std::basic_ostream&lt;class CharT, class Traits&gt;&amp; os, co
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
<i>Effects:</i> Creates a <code>sys_time</code> from <code>t</code> as if by: <i>Effects:</i> Calls <code>to_stream(os, "%F %T", t)</code>.
</p>
<blockquote><pre>
auto tp = sys_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;{t.time_since_epoch()} +
(sys_days{1980y/jan/sun[1]} - sys_days{1970y/jan/1});
</pre></blockquote>
<p>
And then streams that <code>sys_time</code>: <code>os &lt;&lt; tp</code>.
</p> </p>
<p> <p>
<i>Returns:</i> <code>os</code>. <i>Returns:</i> <code>os</code>.
</p> </p>
</blockquote> </blockquote>
<pre>
template &lt;class CharT, class Traits, class Duration&gt;
void
to_stream(std::basic_ostream&lt;CharT, Traits&gt;&amp; os, const CharT* fmt,
const gps_time&lt;Duration&gt;&amp; tp);
</pre>
<blockquote>
<p>
<i>Effects:</i> Inserts <code>tp</code> into <code>os</code> using the format
string <code>fmt</code> as specified by the
<a href="date.html#to_stream_formatting"><code>to_stream</code> formatting flags</a>.
If <code>%Z</code> is in the formatting string <code>"GPS"</code> will be used.
If <code>%z</code> is in the formatting string <code>"+0000"</code> will be used.
</p>
</blockquote>
<pre>
template &lt;class Duration, class CharT, class Traits&gt;
void
from_stream(std::basic_istream&lt;CharT, Traits&gt;&amp; is, const CharT* fmt,
gps_time&lt;Duration&gt;&amp; tp, std::basic_string&lt;CharT, Traits&gt;* abbrev = nullptr,
std::chrono::minutes* offset = nullptr);
</pre>
<blockquote>
<p>
<i>Effects:</i> Extracts <code>tp</code> from <code>is</code> using the format string
<code>fmt</code> as specified by the
<a href="date.html#from_stream_formatting"><code>from_stream</code> formatting flags</a>.
If <code>%z</code> is present, the parsed offset will be subtracted from the parsed time.
If <code>abbrev</code> is not equal to <code>nullptr</code>, the information parsed by
<code>%Z</code> (if present) will be placed in <code>*abbrev</code>. If
<code>offset</code> is not equal to <code>nullptr</code>, the information parsed by
<code>%z</code> (if present) will be placed in <code>*offset</code>.
</p>
</blockquote>
<p> <p>
[<i>Example:</i> [<i>Example:</i>
</p> </p>
@@ -2810,7 +2497,7 @@ int
main() main()
{ {
using namespace date; using namespace date;
using namespace std::chrono; using namespace std::chrono_literals;
auto start = to_utc_time(sys_days{2015_y/jul/1} - 500ms); auto start = to_utc_time(sys_days{2015_y/jul/1} - 500ms);
auto end = start + 2s; auto end = start + 2s;
for (auto utc = start; utc &lt; end; utc += 100ms) for (auto utc = start; utc &lt; end; utc += 100ms)
@@ -2818,10 +2505,10 @@ main()
auto sys = to_sys_time(utc); auto sys = to_sys_time(utc);
auto tai = to_tai_time(utc); auto tai = to_tai_time(utc);
auto gps = to_gps_time(utc); auto gps = to_gps_time(utc);
std::cout &lt;&lt; sys &lt;&lt; " SYS == " std::cout &lt;&lt; format("%F %T SYS == ", sys)
&lt;&lt; utc &lt;&lt; " UTC == " &lt;&lt; format("%F %T %Z == ", utc)
&lt;&lt; tai &lt;&lt; " TAI == " &lt;&lt; format("%F %T %Z == ", tai)
&lt;&lt; gps &lt;&lt; " GPS\n"; &lt;&lt; format("%F %T %Z\n", gps);
} }
} }
</pre> </pre>
@@ -2865,7 +2552,7 @@ class leap
public: public:
leap(const leap&amp;) = default; leap(const leap&amp;) = default;
leap&amp; operator=(const leap&amp;) = default; leap&amp; operator=(const leap&amp;) = default;
// Undocumented constructors // Undocumented constructors
sys_seconds date() const; sys_seconds date() const;